指针、引用

引用

一、什么是引用

引用不是定义一个新的变量,而是给一个已经定义的变量起一个新的别名。
引用定义的格式为 :
类型&引用变量名=已定义过的变量名

引用的特点是:

①一个引用可起多个别名;
②引用必须进行初始化;

int main()
{
    int a=10;
    int& c;
}

上述的错误代码,会发生如下的错误:
这里写图片描述

③引用只能在初始化的时候引用一次,不能再引用其他的变量。
引用举例

int main()
{
    int a=10;
    int b = 10;
    int& c=a;
    int&c = b;
}

如果是上述代码就会出现如下问题:
这里写图片描述

#include <iostream>
using namespace std;

int main()
{
    int a = 10;
    int& c = a;
    cout<<a<<endl;
    cout << c << endl;
    cout << &a << endl;
    cout << &c << endl;
    return 0;
}

生成的结果是:a和c的内容是一样的,a和c的地址也是一样的,也就是说c就是a的一个别名;
这里写图片描述

二、const引用
int main()
{
    int a=10;
    const int& c=a;
    a = 12;//a改变c的值也会随之改变
    //c = 1;//不能给常量赋值



    const int d = 4;
    //int&n = d;//常量具有长性,只有长引用可以引用常量
    const int h = d;

    double i = 5;
    //int& g = i;//i是double类型的,g是int类型的,i赋值给g时要生成一个临时变量,也就是说g引用的是带有常性的临时变量,所以不能赋值
    const int&g = i;
    cout << a << endl;
    cout << c << endl;
    return 0;
}
三、引用做返回值和引用传参

①引用传参
解释:x和y都是实参的引用,不需要经过值传递机制,没有了传值和生成副本的时间,这也就提高了程序的效率。

#include <iostream>
using namespace std;
void swap(int& x, int& y)//形参是实参的别名,改变形参的值就是改变了形参
{
    int tmp = x;
    x = y;
    y = tmp;
}
int main()
{
    int a = 10;
    int b = 20;
    swap(a, b);
    cout << a << endl;
    cout << b << endl;
    return 0;
}

②引用做返回值
*以引用返回函数值,定义函数时需要在函数名前加&
*用引用返回一个函数值的最大好处是,在内存中不产生被返回值的副本。
*返回的对象出了当前的作用域依然存在,最好用引用返回,提高了效率。
1》作为全局变量返回

int ret;//注意ret是个全局变量
int Add1(int x,int y)//返回的是ret的地址
{
     ret = x + y;
    return ret;
}
int& Add2(int x,int y)
{
     ret = x + y;
    return ret;
}
int main()
{
    int a = 2;
    int b = 3;
    ①int m = Add1(a, b);
    //这种方式是最常用的传参方式,返回全局变量ret的值时,C++会创建一个临时变量,并将这个值赋值给临时变量,返回到主函数的时候,把这个临时变量的值赋值给m;int &m=Add1(a, b);
    //这种值传递的方式是有问题的。C++返回的是一个临时变量,而初始化引用m的时候用了临时变量,而临时变量出了作用域会无效,则m就会出现无效的危险。int m=Add2(a,b);
    //这种的方式是最为高效的,函数在计算出ret这个值的时候,C++并不会创建临时变量来发回它,而是直接返回,现在用一个变量的值来接受它,这种方式带来了程序的执行效率。int& m=Add(a,b);
    //这种方式也是比较安全的,函数不创建变量来返回它。而是用了一个引用复制它返回,在主函数中,用了它来给一个引用来赋值,它不是临时变量,所以是安全的。
    cout << ret << endl;
    return 0;
}

2》如果是局部变量

int& Add(int x,int y)
{
    int ret;//这里的ret是一个局部变量
    ret = x + y;
    return ret;
}
int main()
{
    int& m = Add(4, 5);
    printf("%d\n",m);
    return 0;
}//这时候会出现警告, warning C4172: 返回局部变量或临时变量的地址

引用返回时,是取ret的地址到exa寄存器中,不要返回一个临时变量的引用。如果返回对象出了当前的作用域依旧存在时,最好用引用返回,因为这样更高效。

四、指针和引用的对比

1>引用只能在初始化时定义一次(专一性),之后不能改变指向它的指向,而指针变量的指向一直可以改变(之后可以改变它的指向)。
2> 引用必须初始化,但是指针可以初始化,也可以不初始化。
3>sizeof对于指针来说是地址的大小(4字节),但是对于引用来说是它所指向的变量的对应的类型的大小。

double b = 5;
    int *p;
    cout << sizeof(b) << endl;//输出的结果是8
    cout << sizeof(p) << endl;//输出的结果是4

4>指针++:是对它所指向的变量的地址进行++;而引用++:是对初始化它的变量的值进行++;

int b = 5;
    int a = 4;
    int *p=&a;
    b++;
    p++;
    cout << b << endl;
    cout << p << endl;

结果显示的是:
这里写图片描述

5>引用不创建空间;(它只是给已有的变量取了个别名)
6>引用相对于指针比较安全;不存在空引用,并且引用一旦被初始化为指向一个对象,它就不能被改变为另一个对象的引用,显得很安全。
const 指针仍然存在空指针,并且有可能产生野指针。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值