#include <stdio.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);
printf("%s\n",cpp[-1][-1]+1);
return 0;
}
昨天晚上看课看到了上面这一个题,问的是四个printf打印的内容是什么?
因为难度比较大,所以我在这里再回顾一遍,整理一下思路。
首先基本的逻辑如下图所示,因为cp与c之间的连线太乱,所以就没有画,但是对应关系是很好找到的,一看就明白。
1.第一问
printf("%s\n",**++cpp);
对于**++cpp,++的优先级会比*高,所以先算++,但是有一点需要注意,++会永久改变cpp的大小,所以此时cpp不是指向cp的首元素地址了,而是第二位的地址,如下图所示。
在接下来的计算中cpp一直会指向cp的第二个元素的地址,除非再进行++或--计算。此时,**++cpp已经变成了*(c+2),我们解引用c+2的地址,也就得到了c中的第三个元素,所以答案就是point。
2.第二问
printf("%s\n",*--*++cpp+3);
接下来看一下第二问,首先我们要记得,在第一问中,cpp的所指向的地址已经被改变了,现在指向的是cp的第二个元素的地址,接下来我们对*--*++cpp+3进行化简, 第一步还是跟第一问一样,++的优先级最高,所以cpp再加上1,cpp的值再一次改变了,如下图所示。
此时的cpp已经指向了cp的第三个元素。原式也变成了*--(c+1)+3,进一步化简,此时对c+1进行--操作,也就是cp的第三个元素进行--操作,所以此时cp[2]的元素变为了c,如下图所示。
原式也就变成了*c + 3,我们对c进行解引用,得到了c的首元素的地址,也就是e的地址,然后再加3,也就是从e开始数起,所以最终打印的是er。
3.第三问
printf("%s\n",*cpp[-2]+3);
此时对应关系已经变成了下图所描述的样子。
同样的做法,我们对式字进行化简。*cpp[-2]+3,cpp[-2]就相当于*(cpp-2),因为此时cpp指向的是cp的第三个元素,再减去二并解引用,我们便得到了cp的第一个元素,原式就变成了*(c+3)+3,对前面的式子再解引用,得到的是c的第四个元素的地址,也就是f的地址,再加上3,所以从s开始打印,得到的结果就是st。
4.第四问
printf("%s\n",cpp[-1][-1]+1);
第四问就和前面一样了,还是上图的对应关系,对式子进行化简cpp[-1][-1]+1,得到*(*(cpp-1)-1)+1,首先cpp-1并解引用得到cp的第二个元素,原式变为*(c+2-1)+1,然后括号里的式子再化简并解引用,便得到c的第二个元素的地址,即n的地址,然后再加一,便是从e开始数起,所以答案就是ew。
int main(){
char* c[] = {"enter","new","point","first"};
char** cp[] = {c+3,c+2,c+1,c};
char***cpp = cp;
printf("%s\n",**++cpp);//point
printf("%s\n",*--*++cpp+3);//er
printf("%s\n",*cpp[-2]+3);//st
printf("%s\n",cpp[-1][-1]+1);//ew
return 0;
}
完整代码和答案就如上述所示,有不对的地方希望各位大佬积极指正!谢谢大家观看!