这道指针题挺有意思的,将各级指针之间的联系联系起来,仔细分析会发现也不难,重在逻辑思维,做完将会加深你对指针的理解的,好好享受指针带来的乐趣吧!!!
结果是什么呢?
//题目:
int main()
{
char* c[] = { "ENTER","NEW","POINT","FIRST" };
char** cp[] = { c + 3,c + 2,c + 1,c };
char*** cpp = cp;
printf("%s\n", **++cpp);
printf("%s\n", *-- * ++cpp + 3);
printf("%s\n", *cpp[-2] + 3);
printf("%s\n", cpp[-1][-1] + 1);
return 0;
}
我们先把c,cp,cpp之间的关系画出来:
c[ ]数组里放着分别是ENTER,NEW,POINT,FIRST的首字母的地址,而cp里分别放着c+3,c+2
c+1,c,这里的c代表着c数组首元素的地址,cpp里呢存放着cp数组的首元素地址。
我们一个一个分析:
1.
printf("%s\n", **++cpp);
cpp这个指针先+1,表示什么意思呢?cpp这个指针指向的是cp的元素的地址,cpp+1也就是cp元素的地址要+1,所以cpp指向的方向就改变了,然后再解引用找到圆圈1,圆圈1就是右边的方块,而再解引用,就是访问方块里面的圆圈2了,得到圆圈2,圆圈2就是POINT首字母的地址,所以打印的话就会打印出POINT。
2.
还有自增++1或者自减–,都会对变量永久性改变,所以上面的的自增仍然有效。
printf("%s\n", *-- * ++cpp + 3);
先对cpp自增+1,然后解引用,再自减1,再解引用,最后+3.
从上图可以看出,cpp先指向cp的第二个元素的地址,这里自增+1,应该变成指向第三个元素的地址了,然后解引用找到c+1这个地址,再自减,所以c+1变成了c,所以cp这个数组的c+1指向了c,然后解引用找到ENTER的首字母地址,最后+3,就变成E字母的地址了,所以打印出来应该是ER。
3.
printf("%s\n", *cpp[-2] + 3);
cpp[-2]表示什么意思呢?它可以简化成 *(cpp-2),所以这个表达式就是
**(cpp-2)+3. cpp-2,表示cpp指向的c数组的元素的地址要减2,然后解引用找到这个指针保护的地址再解引用最好+3.
4.
上面那个减2可不是永久性的改变喔,只是适用于上面,因为2不是自增和自减,只是-2,cpp的指向并没有改变所以cpp的指向还是解答2中的形式。
printf("%s\n", cpp[-1][-1] + 1);
这个代码可以简化成
*( *(cpp-1)-1)+1
cpp-1使cpp指向c+2,解引用找到红色方块的地址,然后又-1,方块的地址要变成上面的方块的地址了然后解引用,找到NEW的首字母地址,再+1,变成E的地址,最好打印出来应该为EW。
5.
结果:
总结:
- 要理解指针++,是什么在++
是指针指向的元素的地址的自增,而不是单纯的指针+1 - 要理清楚各级指针之间的关系
- 数组名表示首元素地址
- *指针[数字]可以简化成 (指针+数字)