1.原题
看到这样的一道题,和大家分享一下,判断下列代码输出的内容,代码如下:
#include<stdio.h>
#include<stdlib.h>
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);
system("pause")
return 0;
}
2.过程
这题考的是C语言中的指针的应用,我们可以把它的内存图画出来
请注意下标的地址,这四个字符串在内存中的存储位置是随机的,并不一定会连起来。
加下来画出 char* c[ ],由于char* 是一个一级指针,所以c[ ]中存储的就是这四个字符串的地址,假设从 c [ ] 的首地址为 0x2000
接下来是 char** cp [ ],这个中的地址是按照代码中的 c + 3 ,c + 2 , c + 1 , c的顺序排列的
下来是 char*** cpp , 这个根据代码中的内容,这个三级指针中存放的是二级指针的首元素的地址,所以有
下来开始解答代码
printf("%s\n", **++cpp);
这条代码中存在一个优先级的问题,一般在没有括号的情况下是从右往左看的,所以我们首先要看的是 ++cpp 。由上面的分析得到, cpp 现在里面存放的是 二级指针 cp 的地址,所以 ++cpp 也就是给 0x3000 地址 +4 ,因为指针在 32 位的系统中统一占 4 个字节,所以 ++cpp 后 ,就变成了 0x3004 ,在进行解引用,所以这一条代码打印出来的是 " POINT"
printf("%s\n", *--*++cpp + 3);
这条代码与上一条差不多,只不过出现了后面的 + 3 ,按照优先级原则,先从 ++cpp 看起,由于 cpp 中的内容已经变成 0x3004,所以这里再 ++ 的话,就会变成 0x3008 ,解引用一次,对应得到的是 0x3008中对应的内容,也就是 0x2004,再 – ,就得到了 0x2000,再解引用,就得到了 字符串" ENTER " ,后面的 +3 是在 “ENTER”的首地址上加 3 ,也就是指针往后走三个字节,从第四个字节开始打印,一直到遇到 \0 停止,所以这条代码打印出来的内容应该是 “ER”
printf("%s\n", *cpp[-2] + 3);
这条代码显示对 cpp 进行中的内容进行 -2 操作,这里的 *cpp[-2] 也可以表示成 *(cpp - 2),请注意,这里的 - 2 操作并不会改变 cpp 中的值,cpp -2 得到的是 0x3000,解引用后得到 0x200c,其中的内容是 0x400,再 + 3 表示将 0x400中的内容往后移三个字节再打印,所以打印出来的就是 “ST”