05C++引用

1、变量名

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

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

通过变量的名字可以使用内存空间。

2、引用的概念

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

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

用法如下:

#include <iostream>
using namespace std;

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

    a = 11;
    {
        int *p = &a;
        *p = 12;
        cout << a << endl;//12
    }
    b = 14;
    cout << "a=" << a << ",b=" << b << endl;//a=14,b=14
    return 0;
}

引入:

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

程序中通过变量来申请并命名内存空间,通过变量的名字可以使用存储空间。

问题:对一段连续的内存空间只能取一个别名吗?

第一,引用的概念

(1)在C++中新增加了引用的概念;

(2)引用可以看作一个已定义变量的别名

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

(4)引用做函数参数(引用作为函数参数声明时不进行初始化)

比如,有这么一个人,我们称作“姥姥”,也有人称呼是“外婆”,有人问你你姥姥是谁?或者问你你外婆是谁?我们知道这两个称呼指的是同一个人,你妈给了你姥姥一千块钱,你姥姥多了一千块钱,那么你外婆也就多了一千块钱,你外婆又给了你五百块钱压岁钱,那你姥姥也就是少了五百块钱。姥姥 == 外婆,通过修改外婆持有的资产数额,就修改了姥姥持有的资产数额!

运行以下程序,变量a的别名定义为b,我们修改a的值就修改了b的值,修改b的值就修改了a的值。

E:UserslsjDesktop1.png

E:UserslsjDesktop2.png

第二,通过引用交换两个变量的值

E:UserslsjDesktop3.png

E:UserslsjDesktop4.png

我们知道这个程序是无法实现交换两个数值的,如果想交换两个数值,按照以前的办法就是使用指针,这里不多说。

我们学习了引用之后可以通过引用来实现交换两个变量的值。

如下程序,x、y是实参,a、b是形参,将实参x、y赋值给形参a、b,a、b就是x、和y的别名,改a、b就是把x、y的数值改了。

E:UserslsjDesktop5.pngE:UserslsjDesktop6.png

3、规则

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

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

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

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

#include <iostream>
using namespace std;

int main(void)
{
    int a,b;
    int &r = a;
    int &r = b;//error,不可更改原有的引用关系——规则(2)
    float &rr = b;//error,引用类型不匹配——规则(1)
    cout <<"&r="<< &r << ",&a=" << &a << endl;//变量与引用具有相同的地址——规则(1)
    int &ra = r;//可对引用再次引用,表示a变量有两个别名,分别是r和ra——规则(3)

    return 0;
}

4、引用作为函数参数

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

#include <iostream>
using namespace std;

struct Teacher
{
    char name[64];
    int age;
};
void printfT(Teacher *pT)
{
    cout << pT->age << endl;
}

void printfT2(Teacher &pT)//pT是t1的别名,相当于修改了t1
{
    pT.age = 33;
    cout << pT.age << endl;
}

void printfT3(Teacher pT)//pT和t1是两个不同的变量
{
    cout << pT.age << endl;
    pT.age = 45;//只会修改pT变量,不会修改t1变量
}

int main(void)
{
    Teacher t1;
    t1.age = 35;

    printfT(&t1);//35

    printfT2(t1);//33,pT是t1的别名
    printf("t1.age:%d
", t1.age);//33

    printfT3(t1);//33,pT是形参,t1拷贝一份数据给pT
    printf("t1.age:%d
", t1.age);//33

    return 0;
}

5、引用的意义

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

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

c++中引入引用后,可以用引用解决的问题避免用指针来解决。

#include <iostream>
using namespace std;

struct student
{
    int age;
    char name[64];
};
void swap1(int *a, int *b) 
{
    int temp;
    temp = *a;
    *a = *b;
    *b = temp;
}

void swap2(int &a, int &b)
{
    int temp;
    temp = a;
    a = b;
    b = temp;
}

void printS1(struct student s)//子拷贝方式:student s=s1;结构体整个值拷贝的动作
{
    cout << s.age << " " << s.name << endl;
}

void printS2(struct student *sp)//指针方式
{
    cout << sp->age << " " << sp->name << endl;
}

void printS3(struct student &sp)//引用方式:student &s=s1;
{
    cout << sp.age << " " << sp.name << endl;
}

int main(void)
{
    int a = 10;
    int b = 20;
    swap1(&a, &b);
    cout << "a=" << a << ",b=" << b << endl;//a=20,b=10

    int c = 100;
    int d = 200;
    swap2(c, d);
    cout << "c=" << c << ",d=" << d << endl;//c=200,d=100

    student s1 = { 10,"zhang3" };
    printS1(s1);//10 zhang3
    printS2(&s1);//10 zhang3
    printS3(s1);//10 zhang3
    return 0;
}
原文地址:https://www.cnblogs.com/xinmomoyan/p/10606732.html