看到本題是在搜狗某年的筆試題上,看也沒人給出非常詳細的講解,直接給出了答案,我來嘗試寫一寫,錯誤之處園友們指教.
貌似本題來源自<The C Puzzle Book> ,搜狗也只是換了一下字符串,直接看題吧
#include <stdio.h> char *c[]={"ENTNG", "NST","AMAZI","FIRBE"}; char** cp[]={c+3, c+2, c+1, c}; char ***cpp= cp; int main() { printf("%s",**++cpp); printf("%s ",*--*++cpp+3); printf("%s",*cpp[-2]+3); printf("%s",cpp[-1][-1]+1); }
請寫出程序的執行結果....
首先從左到右看:
char *c[]= { "ENTNG", "NST", "AMAZI", "FIRBE" };
*c[] 是一個字符,因此,c[]是指向該字符,c就是一個數組(數組的內容為指向字符的指針),c已經被初始化了.
char** cp[]={c+3, c+2, c+1, c};
再看第二行,**cp[]是一個字符,*cp[]就是一個指針,指向該字符,cp[]就是一個指針,指向該指針,而cp就成為了指針數組,內容是指向字符的指針的指針。並且通過c的元素進行了初始化
char ***cpp= cp;
第三行,***cpp是一個字符,**cpp指向該字符,*cpp指向該指針,cpp就指向該字符的指針的指針.
然后我畫一張圖表示初始的情況看看
然后對於下面的輸出語句,通過操作符優先級使用括號來區分一下:
*(*(++cpp));
這個嘛,就是把cpp后移(注意cpp已經改變了)然后就指向了cp[1],然后兩次取其值即可得到AMAZI
推導過程如下:
++cpp -> cp[1] // cp[1] -> c+2 ++cpp = &cp[1] // &(c+2) *++cpp = *(&c+2) // c[2] **++cpp = *&c[2]
然后看第二個
(*(--(*(++cpp))))+3;
加括號后如上,cpp再加一,就指向了cp[2],取一次值(也就是*號)就變成了c[1],然后--c[1]就指向了c[0],取值就成了c[0]的地址,然后地址+3,就是NG了
(*(cpp[-2]))+3;
上面,cpp指向cp[2]了,然后呢,cpp[-2] 相當於*(cpp-2),間接引用cp[2],這樣cpp[-2]就指向了cp[0]了,然后,就是FIRBE了,加3就是BE了
最后
(cpp[-1][-1])+1;
cpp還是之前的cp[2],cpp[-1][-1]相當於*(*(cpp-1)-1),先減1指向了cp[1],取一次值就是c[2]了,然后c[2]-1就成為c[1]了,然后+1之后就是ST了.
所以,最后輸出就是
AMAZING BEST
錯誤之處還望指正.
我的博客:http://leaver.me