C++引用、指针、const理解
1.C++指针及引用
从最简单的三行开始
int i = 10;
int* pi = &i;
int& refI = i;
首先i
是一个int
类型的常量,pi
是一个指针,指向的是i
的地址,换句话说pi
的内存里存放的内容是i
的地址,二者都存在于栈区。
也就是说pi
即指针的加减变化,就是内存中地址的加减变化,而*pi
则是该地址存储的内容。所以当我们执行(*pi)++
的时候,也就是pi
指向的地址对应的那块内存上,存储的值在进行运算。故而(*pi)++
之后,i的值变成11
。
对此我们可以看到,指针直接对内存进行操作,太过于强大,万一控制不好可能会出现比较大的问题,所以出现了引用int& refI = i;
引用实际上是一种对指针的操作的阉割处理,pi
可以到处乱窜,只要稍微一变动就可以指向别的地址,而引用我们可以理解为是只指向i
的地址的指针。
某种意义上来说int& refI = i;
等同于int* const refI = &i;
(*refI
可以改,但是refI不可以改)。或者说,将引用称为变量的别名也十分贴切,你叫张三的时候是你,你换个名字还是你。、
ps:对于C++来说,编译器不会将引用视作对象,每次对引用的操作其实操作的都是引用指向的对象,所以引用必须每次都要赋初值。
2.const杀疯了
2.1 int const i;
与const int i;
两个完全相等,都是被const修饰了之后,被编译器认为是常量的存在,不可以被二次修改。
2.2 int const* pi = &i;
与const int* pi = &i;
(*pi不可变,pi可变)
上述两种写法表达的含义完全相同,指向常量的指针,pi
指向的地址可以变化,但是pi
指向的地址所存放的值不可以修改。
int i = 10;
int j = 20;
int const* pi = &i;
pi = &j;
上述代码可以直接执行,这是完全正确的,执行完成之后的结果为pi
存储的值是j
的地址,*pi
的值是20
;
但是如果试图执行(*pi)++;
就会发现编译错误。也就是说,pi这个指针指向的地址是可以变换的,但是如果直接通过pi来修改指向地址的值是不可以的。
2.3 int* const pi = &i;
(*pi可变,pi不可变,某种意义上等同引用)
这条语句与上述2.2中的作用正好相反,其表达的含义是pi
指向的地址是不变的,但是pi
指向地址的值是可以变化的,是不是与int& pi = i;
有异曲同工之妙,某种意义上这两种是相等的存在。
int i = 10;
int* const pi = &i;
(*pi)++;
cout << i;
上述代码是完全没有问题的。执行完之后i的值会变成11;
关于2.2和2.3中记忆的小方法:
1.const在类型左边还是右边的修饰是没有区别的。
2.const
在*
的左边时,*
和pi
是一伙的,修饰的是*pi
,(*pi
不可变);
const
在*的右边时,const
把*
和pi
分开了,只剩下pi
自己了,修饰的pi
(pi
不可变)
2.4const int* const pi = &i;
很明显是 2.2和2.3的结合体,*pi
不能变,pi
也不能变。
3 建议
建议直接上手写一写,会比自己看书或者听视频,清楚的快一些,多看看其实也就不绕了。因为这还不是最绕的。