漫谈C++引用与指针

引用

先声明:引用的本质是const指针,以下内容只帮助理解.

我的面前放了一个包裹,名字叫a。

int a = 0;//值为0的int型变量(一个对象)

我大喊一声:“xx处有个包裹a!” 这句完整的话语,称为b。

int &b = a; //引用b绑定给对象a

通过我说的的这句话,你可以找到包裹a的位置,获取里面的资源。

你可以这样理解:

  • 这句话只有在明确表示包裹位置时才有意义(引用必须被初始化
  • 已经说出口的话不能收回修改,除非我再说另一句话告诉你新的情况(引用只能绑定一次,不可再绑定给另一个对象
  • 至于我刚才说的话,你无法真正触碰到它,我也没法告诉你那句话去哪里了(不能定义引用的引用

指针

然后我又放了一块指示牌,名字叫p1,写上一句话:“XX处有个包裹a”

int *p1 = &a;//&是取地址符,所以&a就是那句话

也许做上面这些事的过程中我累了,我会选择分两段进行,先休息一会,再把内容补上,也没有问题。

int *p1;//定义指针变量p1
p1 = &a;//a的地址赋值给p1

注意:

  • 指示牌是专门用来告诉人们东西所处位置的(指针存放对象的地址
  • 我可以先放牌子,再写内容(指针不用初始化),或写上“这是块假的指示牌”(生成空指针),但诸如此类的牌子同样使人迷惑(不能用于访问对象
  • 一块牌子可能不够看的,我可以再放一块牌子p2,把上一块牌子p1的内容照抄过去, 就像这样,如此一来我相当于有了两块功能一样的牌子——p1和p2,它们虽然摆放的位置不同,但都指向同一个包裹。
int *p2 = p1;//p2的值就p1的值
  • 由于指示牌和包裹一样是实实在在的物体(指针本身是对象),所以我可以再放一块牌子,上面告诉你第一块牌子的位置(可以用一个指针的地址给另一个指针赋值),于是我可以通过名为p3的指示牌顺藤摸瓜找到p1,最后一样找到了包裹a
int **p3 = &p1;
std::cout << **p3 ;
  • 对了,之前说过,我没法告诉你【我说的话】去哪了,同样的,用牌子写字的方式也没法告诉你它去哪了(不能定义指向引用的指针

总结

如果以上的瞎扯不是很让人理解,那么可以参照下面的代码总结:

#include<iostream>
using namespace std;
int main()
{
    /*
        int *x  * 定义指针类型
        int &x  & 定义引用类型
        *x      * 解引用符
        &x      & 取地址符
        直接使用x,得到x对象本身
        如果x的值是地址,x前面加上*后,得到那个地址的变量的值
        x前面加&,得到x的地址
    */

    int a = 1;//变量
    cout << "value of a: " << a << endl;//1
    cout << "address of a: " << &a <<endl;//0x61fe04
    
    int &y = a;//引用(本质是常量指针,相当于int *const y = &a;)
    //这里其实不是y的值,而是a的值(相当于*y)
    cout << y << endl;//1
    //这里不是y的地址,是a的地址(相当于&(*y))
    cout << &y << endl;//0x61fe04
    
    int *p1 = &a;//指针
    //p1的值就是a的地址
    cout << p1 << endl;//0x61fe04
    //p1值所指向的目标,就是a
    cout << *p1 << endl;//1
    //p1的地址
    cout << &p1 << endl;//0x61fdf8
	
	//把p1的值,也就是a的地址赋值给p2,此时 p1 == p2 && *p1 == *p2
    int *p2 = p1;
    //p2的值就是a的地址
    cout << p2 << endl;//0x61fe04
    //p2的值等于a的地址,所以*p2是a的值
    cout << *p2 << endl;//1
    cout << (p1 == p2 && *p1 == *p2) << endl;//1
	
	//把p1的地址赋值给p3,p3是个指向指针的指针
    int **p3 = &p1;
    //p3的值就是p1的地址
    cout << p3 <<endl;//0x61fdf8
    //p3值所指向的目标是p1,所以*p3相当于p1
    cout << *p3 << endl;//0x61fe04
    //而p1的值是a的地址,所以*p3等于a的地址
    //所以在*p3基础上再解一次引用就是a本身了
    cout << **p3 << endl;//1
    
    return 0;
}

对于*解引用符号,这里只有输出的用法,赋值也是一样的,对*p1赋值就是对p1所指的对象赋值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值