看代码先,下面的讲解都是针对这篇代码:
#include
#include
using namespace std;
void main(void)
{
char *a[]={"abc","cde","fgh"};//字符指针数组
char **b=a;//定义一个指向指针的指针,初始化为字符指针数组的首地址
cout<<*b<<"|"<<*(b+1)<<"|"<<*(b+2)<<endl;
cout<<**b<<'|'<<*b+1<<'|'<<**b+1<<'|'<<**(b+1)<<'|'<<*(*b+1)<<endl;
}
说明:
b中存储的是{"abc","cde","fgh"}的首地址,*b中存储的是"abc\0"的首地址。
*b为一级指针,b的值为{"abc","cde","fgh"}的首地址,所以*b的值为"abc\0"。
*(b+1)为一级指针加1后,再取地址指向的内容,所以*(b+1)的内容为'cde\0"。
*(b+2)的内容为"fgh\0"
**b为二级指针,由于*b的值为"abc\0"的首地址,所以**b的内容为'a'。
*b+1为'a'的地址加1,即为字符'b'的地址,在c++中,输出字符指针就是输出字符串,程序会自动在遇到\0后停止.所以*b+1输出为"bc"。
**b+1为**b(二级指针,字符'a')加1,就是'a'+1,所以值为98。
**(b+1)的内容为字符'c'。
*(*b+1),因为*b为"abc\0"的首地址,则*b+1的加1操作实际移动了1个单位,所以*(*b+1)指向'b'。
如果,大家看到这里还是不能理解的话,我不妨拿出我本人的独门武器了。
以下程序的运行结果是多少?
#include usingnamespacestd; intmain() { intnum[5]={1,2,3,4,5}; cout<<*((int*)(&num+1)-2)<<endl; return0; }
&num+1就指向二维数组的第二行,所以转型(将int **转为int *)后就相当于指向num[4]后的第一个位置,所以再减2就指向num[3],既是4!
总结:关于二级指针的问题,相对比较麻烦,尤其是关于二级指针的自加自减操作更难理解。那么二级指针主要用在什么地方呢?首先,二维数组的引用有可能会用到二级指针,遍历数组的元素等常规操作;然后,字符串数组的应用,例如上边第一个例子。总结二级指针的加减,一级指针必须对应相应的数组类型(常规类型的数据类型可以定义二级指针,但其加减并无实际意义),最好的就是像引用数组那样应用。