摘抄自:https://blog.csdn.net/w_y_x_y/article/details/78572236
题目代码如下:
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;
}
输出结果如下:
这里写图片描述
我们来一步步解析代码:
char *c[] = {"ENTER","NEW","POINT","FIRST"};
这是一个“指针”数组,每个元素存的是每个字符串的首字符的地址
如图:
这里写图片描述
char **cp[] = {c+3,c+2,c+1,c};
这是一个“二级指针”数组,每个元素存的是“指针”数组c 的每个空间的地址
如图:
这里写图片描述
char ***cpp = cp;
这是一个三级指针,指向“二级指针”数组cp的首地址
如图:
这里写图片描述
printf("%s\n", **++cpp);
首先来解析这段代码:
**++cpp //分解成下面几步
++cpp //cpp自增一,如下图
*(++cpp) //cpp指向cp[1]的空间,取cp[1]内的元素,即c+2。
*(*(++cpp)) //对其解引用,取到"POINT"的首字符地址
//所以结果输出"POINT"
这里写图片描述
继续看下条代码:
printf("%s\n", *--*++cpp+3);
仍然先解析代码:
*--*++cpp+3 //分解成下面几步
++cpp //cpp自增一,如下图
*(++cpp) //对自增后的cpp解引用,取到c+1,即c[1]的地址
--(*(++cpp)) //对c+1自减一,取到c[0]的地址
*(--(*(++cpp))) //对其解引用,取到"ENTER"的首字符地址
*(--(*(++cpp)))+3 //将"ENTER"的首字符地址+3,得到字符'E'的地址
//所以结果输出"ER"
这里写图片描述
继续看下条代码:
printf("%s\n", *cpp[-2]+3);
解析代码:
*cpp[-2]+3 //分解成下面几步
cpp[-2] //相当于*(cpp-2),其代表的地址下如图,取到c+3,即c[3]的地址
*(cpp[-2]) //对其解引用,即*(c+3),取到字符串"FIRST"首字符的地址
*(cpp[-2])+3 //指向字符串"FIRST"中的字符'S'的地址
//所以输出"ST"
这里写图片描述
继续看下一条代码:
printf("%s\n", cpp[-1][-1]+1);
解析代码:
cpp[-1][-1]+1 //分成下面几步
cpp[-1] //相当于*(cpp-1),其代表地址如下图,取到c+2
(cpp[-1])[-1] //相当于(c+2)[-1],相当于*((c+2)-1)
//取到字符串"NEW"首字符的地址
//其代表地址如下图
(cpp[-1])[-1]+1 //指向字符串"NEW"中字符'E'的地址
//所以输出"EW"
image.png
网友评论