C++中指针和引用两个基本概念讲解
====================第一部分====================
编程其实就是跟编译器对话,用C++编程无非就是跟只懂C++的编译器进行对话。
按照C++语言规则,我得跟编译器这么说话它才能听懂:
mlx FangWei = 南方;
mlx就是某类型(特意虚构一个类型,为了让理解更有普适性),FangWei就是变量,南方就是保存在这个变量里的内容。紧接着我又对编译器说:
mlx *zz1 = &FangWei;
C++规定赋值操作符“=”两边的变量类型必须相符,所以这里必须先同样写一个mlx,然后用 * 告诉编译器这个zz1是个指针,区别于其他形式的变量!
那么为什么会有个&呢?因为实际上指针是用于保存所指对象之“住址”的盒子(特意用“住址”是为了更形象一点,所有对象在内存中皆有住址)。这里的&就是取地址操作,它跟“引用”中的&(用于起别名)是有概念上的不同的!以上语句就是让编译器给我把FangWei在内存中的地址保存到zz1里。
好了,现在我要让编译器回答我了,有来有往才叫对话!所以我又说了:
cout << zz1 << endl;
cout << *zz1 << endl;
前一句是要求编译器给我看zz1到底保存了什么地址,后一句话是让编译器告诉我这个地址到底住了个什么鬼。注意这里的 * 这个符号已经不是要表达“后面跟一个指针”这个含义了,而是一个操作符,它告诉编译器进行“解引用操作“!但我个人总感觉它是跟&对应的,应该叫“取对象操作”(对应于&叫“取地址操作”)!
至此,编译器知道我说什么并且回答我了:
0055FB60
南方
编译器告诉我,我要的zz1盒子里保存了一个地址0055FB60,里面住着一个叫南方的东西。
====================第二部分====================
如果以上部分理解都对,下面就是我比较头痛的了,指针的指针!
mlx **zz2 = &zz1;
这句话的意思是,我告诉编译器定义一个指针zz2,所指对象是zz1,根据定义指针是保存所指对象之住址的盒子,那么zz2就是保存zz1之住址的盒子,但是这个住址现在不知道,要通过cout指令显示出来。注意这个住址不是“南方”的那个0055FB60,而是zz1自己的住址。切记,指针也是一种对象,凡对象必有一段内存地址。
所以,当我最后说:
cout << zz2 << endl;
这就是让编译器告诉我zz1本身的地址,也就是zz1到底住在内存条的哪个角落!
我又说:
cout << *zz2 << endl;
加了一个 * 运算,进行“解引用”(我理解为“取对象”),让编译器告诉我这个角落里住着谁 – 其实就是住着zz1
我又说:
cout << **zz2 << endl;
再加一个 * ,就是既然 *zz2 得到的是 zz1,正好 zz1 又是个指针,保存了南方的住址,所以**zz2继续取对象,就得到了南方本人了。
综上,编译器对我以上三句话的回答分别是:
0078CC34 // 指针zz1的住址
0055FB60 // 变量FangWei的住址,同时是zz1这个盒子里保存的内容
南方
总结一下*和&:*在声明定义的时候当做指针的类型修饰符,其他时候例如表达式或者要cout的时候就是解引用(取对象),同样的,&在声明定义的时候是作为引用的修饰符来使用,其他时候就是取地址操作符,这里千万不能搞错了。
====================第三部分====================
最难的来了!“指向指针的引用”和“指向引用的指针”如何理解?
继续贯彻“指针是保存所指对象之住址的盒子”以及“引用是对所指对象另一个名字绑定”这两种理解:
“指向指针的引用”是存在的,因为指针本身是有内存住址的对象,这个引用用一个别名绑定了这个指针!
“指向引用的指针”不存在!引用本身不是对象,没有内存住址,所以也就无法用一个指针指向这个地址!
大白话地说!就是一个指针除了保存了别人的地址,它自己也有一个地方住,是个实物(所以它的住址又可以被另一个指针指着),但是引用仅仅是别人名字的绑定,是没有实际住址的,编译器也不会把变量内容拷贝到这个名字下!比如我把前文说的南方的名字FangWei引用给FangXiang:
mlx &FangXiang = FangWei;
那么这个FangXiang只是一个引用,这个引用只是FangWei的别名!南方还是住在FangWei中,还是住在0055FB60中!所以指针不能指向FangXiang,只会指向FangWei!
====================第四部分====================
“指向指针的指针”存在
“指向指针的引用”存在
“指向引用的指针”不存在
结语:我总觉得这些约定俗成的翻译解释极大妨碍了初学者学习,以上三句话明明可以说成“存放某指针地址的另一指针”,“绑定了某指针名字的别名”,以及存放绑定了某对象的别名的地址的指针。当然最后一句话是不存在的,因为绑定了某个对象的别名本身不是对象,没有内存地址的,所以也就不存在指向这个别名的指针,但这个别名的本体有,所以存在指向这个本体的指针。
上一篇: 生产Web架构优化方案(动态转静态)
下一篇: 简单的mysql备份教程