c语言最强的莫过于指针,c++程序猿,对它也是又爱又恨,它很强大却很容易让人弄混以至于出错(错误一般出的不小)。博主也被它弄的死去活来。(本文纯属博主理解,有错请指出,谢谢)
问题1
$ int val = 20;
$ int *p;
$ p = &val;
$ int val = 20;
$ int *p = &val; // p存放着val的地址,或者说p是指向变量val的指针
这是博主纠结的第一个问题,许多程序在开始声明指针和使用指针,有以上两种写法。第一种是不直接初始化指针,系统将会给指针p一个不确定的值,然后在用val来初始化指针。第二种是直接在声明是初始化指针p。baidu和google均无果。
$ int val = 20;
$ int* p;
$ p = &val;
$ int val = 20;
$ int* p = &val;
换一种写法,将 *和类型写在一起,就好理解多了。由上可知p是一个int型指针,*p 就是int类型。所以上面的就很好理解了,都是将val存放的地址赋给p,让p来存放val的地址。
问题2
操作符在c++程序中有多个作用,一个就是乘号,另一个是解引用符。:如果指针指向了一个对象,则会使用*(解引用符)来访问该对象。
$ int val = 20;
$ int* p = &val;
$ cout << p << endl; // 输出:地址
$ cout << *p << endl; // 输出:20
cout << p 将会输出p存放val的地址值。如果需要输出p所指对象的值则需要* 来解除引用,得到指针p所指的对象,*其实是一个暴露作用,将p所指的对象的值暴露出来。
问题3
$ cout << p << " " << &p << endl;
运行结果:
p存的地址和&p取得地址值总是差4
$ if(p == &p)
$ cout << "Yse" << endl;
$ eles
$ cout << "No" << endl;
博主将p和&p进行比较看他们的差别,错误指出这是int*和int**之间的比较。所以&p是一个int**类型.
p存放的是val的地址,而&p存放的是指针p的地址
$ cout << p << " " << *&p << endl;
此时p和&p的地址却是一样的!似乎又回到了问题2上了&p是指针p的地址值,此时作为解引用符,将&p的内容暴露出来了,即p的地址,所以p和*&p的地址是一样的。
问题4
#include<iostream>
using namespace std;
int main()
{
int i;
int* pi;
int** ppi;
ppi = π // 1
*ppi = &i; // 2
i = 'a'; // 字符a的ascll码为97
cout << i << " " << *pi << " " << **ppi << endl;
cout << &i << " " << &pi << " " << &ppi << endl;
cout << pi << " " << ppi << endl;
return 0;
}
结果:
语句1 把ppi初始化为指向变量pi,就可以安全对ppi执行间接访问操作
语句2 把pi(通过ppi间接访问)初始化为指向变量i。
间接访问可以更好的理解指针。当间接访问的层次越多,需要使用的次数则会越少(摘自《c与指针》)