C++对C语言的拓展

引用

变量名 

  变量名实质上是一段连续存储空间的别名,是一个标号(门牌号)    

  通过变量来申请并命名内存空间.    

  通过变量的名字可以使用存储空间.  

引用的概念 

变量名,本身是一段内存的引用,即别名(alias).  引用可以看作一个已定义变量的别名。    

引用的语法:Type&  name  =  var;

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;

int main()
{
    int a = 10;    //c编译器分配4个字节内存, a内存空间的别名
    int b = 30; 

    int *p = &a;    //&a是取a的地址
    *p = 30;

    p = &b;
    *p = 20; //b

    int &re = a;    //int & 使用引用数据类型, re就是a的别名
    re = 50;        //则a = 50

    re = b;            //此时不是让re成为b的引用 而是把b的值赋值给re
    re = 50;

    cout << "a=" << a << endl;
    cout << "b=" << b << endl;


    system("Pause");        //阻塞功能
    return EXIT_SUCCESS;    // 返回正常退出
}

 结果:

 规则 

1  引用没有定义,是一种关系型声明。声明它和原有某一变量(实体)的关 系。故而类型与原类型保持一致,且不分配内存。与被引用的变量有相同的地址。     

2  声明的时候必须初始化,一经声明,不可变更。     

3  可对引用,再次引用。多次引用的结果,是某一变量具有多个别名。     

4  &符号前有数据类型时,是引用。其它皆为取地址

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;

void test()
{
    int a = 10;
    int b = 20;
    //int &r;    //error 引用一定要初始化, 起别名一个得先有个名
    int &r = a;
    //int &r = b; //error 不可改变原有的引用关系,一经声明,不可变更
    int &r2 = r;    //可对引用再次引用,表示a变量有两个别名 分别是r 和 r2

    float &r3 = a;    //error 引用类型不匹配, 变量和引用具有相同地址,类型要与元类型一致
}

引用作为函数参数

struct Person
{
    int age;
};

void ChangeVal(int &r) //当我们将引用作为函数传递时,编译器会替我们将实参,区地址给引用 即:int &r = &a (传递过来的实参a自动取地址)
                      //相当于int &r = a 
{
    r = 300;        //对一个引用操作赋值的时候,编译器替我们隐藏*操作 若: *r = 300
}
void ChangeVal2(int* r) //int* r = a 传递实参要加& 
{
}
void motify(int *const r ) //int *const r = a
{}

void AllocatMemory(Person **p)  //**p 具体的Person对象 *p对象的指针 p 指针的指针 ???
{
    *p = (Person*)malloc(sizeof(Person));
    (*p)->age = 18;
}
void test01()
{
    Person* p = NULL;
    AllocatMemory(&p);
    cout << "age=" << p->age << endl;
}
void AllocatMemory2(Person* &p)  //利用指针引用开辟空间
{
    p = (Person*)malloc(sizeof(Person));
    p->age = 28;
}
void test02()
{
    Person* p = NULL;
    AllocatMemory2(p);
    cout << "age2=" << p->age << endl;
}

普通引用在声明时必须用其它的变量进行初始化,引用作为函数参数声明时不进行初始化。  

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;

struct Teacher
{
    char name[64];
    int age;
};
//pT和t1是两个不同的表里
void printfT(Teacher pT)
{
    pT.age = 20;        //只会修改pT变量 不会修改t1变量
    cout << "T函数内:"<< pT.age << endl;
}

void printfT2(Teacher *pT)
{
    pT->age = 24;        //利用指针修改变量
}

void printfT3(Teacher &pT) //pT是t1的别名,相当于t1
{
    pT.age = 26;
}

int main()
{
    Teacher t1;
    t1.age = 18;

    printfT(t1);
    cout << "T:t1.age=" << t1.age << endl;

    printfT2(&t1);
    cout << "T2:t1.age=" << t1.age << endl;

    printfT3(t1);
    cout << "T3:t1.age=" << t1.age << endl;

    system("Pause");        //阻塞功能
    return EXIT_SUCCESS;    // 返回正常退出
}

结果

引用的意义

1)引用作为其它变量的别名而存在,因此在一些场合可以代替指针

2)引用相对于指针来说具有更好的可读性和实用性  

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
void swap2(int a, int b);    //无法实现两个数据的交换
void swap3(int *p, int *q);    //开辟两个指针空间实现交换

void swap(int &a, int &b)
{
    int tmp;
    tmp = a;
    a = b;
    b = tmp;
}
int main()
{
    int a = 3, b = 4;
    swap(a, b);
    cout << "a=" << a << ", b= " << b << endl;
    
}

const引用

1.如果要对一个常量进行引用,必须是一个const引用

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;

int main()
{
    const int a = 10;
    int &re = a;    //err 
    const int &re2 = a;    //ok
    system("Pause");        //阻塞功能
    return EXIT_SUCCESS;    // 返回正常退出
}

2.一个普通变量,可以用一个const引用接收,但是原变量可以更改,const引用改变不了

    int b = 20;
    const int &re3 = b;    //ok
    re3 = 30;    //err
    b = 30;        //ok

    cout << "re3=" << re3 << endl; //30
原文地址:https://www.cnblogs.com/yifengs/p/15096833.html