最近遇到了一道面试题,贼恐怖!
这是一道集合了数组,一至三级指针,操作符结合性与优先级,字符串的魔鬼题目!
如果你能面不改色心不跳的完全做对,兄弟!你真滴niubility!
话不多说!上题!诸君且往下看:
题目
#include <stdio.h>
#pragma warning(disable:4996)
int main()
{
char* c[] = { "enter","new","point","first" };
char** cp[] = { c + 3,c + 2,c + 1,c };
char*** cpp = cp;
printf("%s\n", **++cpp); //1
printf("%s\n", *--*++cpp+3); //2
printf("%s\n", *cpp[-2]+3);//3
printf("%s\n", cpp[-1][-1]+1);//4
return 0;
}
且让小弟问一句,宁把结果得出来没?不要急着看解析,这边建议宁自己做一下,然后跳转结果,看做的对不对,然后再做一遍,如果还做不对,且容我慢慢分析!
给你指出注意事项
1. 操作符++、--
的优先级比*
高
2. 操作符++、--
会改变数据本身
int a = 0;
a++; //a = a + 1; // a由0变1
a--; //a = a - 1; // a由1变0
++a; //a = a + 1; // a由0变1
--a; //a = a - 1; // a由1变0
3. 操作符[]
自带解引用效果
4. char *str = “ChioaR”
中的ChioaR
字符串保存在地址空间的字符常量区
5. char *str = “ChioaR”
这样定义的字符指针仅仅指向ChioaR
中的C
,也就是说str
里存着C
的地址
注意事项说完了,要不考虑自己再做一下?
分析
根据以下三行代码,画出下图应该是没有问题。
绿色线条带条小斜线都表示指向。
char* c[] = { "enter","new","point","first" };
char** cp[] = { c + 3,c + 2,c + 1,c };
char*** cpp = cp;
解题开始!
1
printf("%s\n", **++cpp);
过程图解:
蓝色箭頭为本次过程路线
分析:首先,cpp
本来指向cp[0]
,++
后,cpp
指向cp[1]
,再解引用,拿到了cp[1]
,cp[1]
指向c[2]
,再解引用拿到c[2]
,c[2]里存的"point"
的首地址,%s打印,结果:point。
流程如下:
2
printf("%s\n", *--*++cpp+3);
过程图解:
红色箭頭为本次过程路线
分析:首先,因为上句把cpp的指向已经改了,所以……。cpp
本来指向cp[1]
,++
后,cpp
指向cp[2]
,*
后拿到了cp[2]
,--
也就是--cp[2]
,导致cp[2]
指向c[0]
,*
后,拿到了c[0]
,c[0]
指向"enter"
的‘e’的地址,+3
也就是c[0]+3
,令c[0]指向"enter"
的‘e’,%s打印,结果:er
流程如下:
3
printf("%s\n", *cpp[-2]+3);
过程图解:
黑色箭頭为本次过程路线,虚线表示并没改变cpp的指向
分析:首先,cpp
指向cp[2]
,cpp[-2]
相当于*(cp-2)
,拿到c[3]
,再解引用,拿到"first"
的f
地址,+3
拿到"first"
的s
地址,%s打印,结果:st
流程如下:
4
printf("%s\n", cpp[-1][-1]+1);
过程图解:
橙色箭頭为本次过程路线
分析:首先,cpp
指向cp[2]
,cpp[-1]
相当于*(cp-1)
,拿到c[2]
,cpp[-1][-1]
相当于*(c[2]-1)
,拿到new
的n的地址,+1,拿到new
的e
的地址,%s打印,结果:ew
流程如下:
结果
附注
可能文中一些地方说的还不是很清楚,欢迎大家一起交流探讨