C语言大神进来看看这个题目
之前一個讀者給我發的一個題目,我大概看了下,題目的難度還是比較大的,而且考察的內容也比較多,可能在實際項目上使用比較少,估計十幾年的老碼農都沒有用過,但是在看大神的代碼的時候,就特別考驗基本功,能不能理解理解別人的代碼非常重要。
題目如下
就直接printf出幾個的輸出值,比較自信的大神可以直接回復答案,可以看看自己的答案對不對。
#include <stdio.h> char *c[] = {"HELLO","NEW","WORLD","SAYHI"}; char **cp[]={c+3,c+2,c+1,c}; char ***cpp=cp; int main(void) { printf("%s\n",*cpp[2]); printf("%s\n",**++cpp); printf("%s\n",*--*++cpp+3); printf("%s\n",**cpp); printf("%s\n",*cpp[-2]+3); printf("%s\n",cpp[-1][-1]+1); printf("%s\n",cpp[-1]); }圖示解析
解題過程
c 是一個數組,數組里面存的東西是 char *, 類型 cp 也是一個數組,數組里面存的東西是 char **, 類型 cpp 是一個指針,cpp 是一個三級指針,三級指針只能存二級指針地址
我用 gdb 調試如下從 gdb 調試可以看到 cpp 存的是一個地址,這個地址就是 &cp 也就是 0x601060
cp 是數組,里面的數組存的是 char ** ,如果我們想拿到 char * 的字符串,就需要使用 *p[x] 來獲取里面的字符串
比如
幾個printf 的輸出結果
1、printf("%s\n",*cpp[2]);
實際上獲取的就是 c+2 也就是 NEW 字符串
2、printf("%s\n",**++cpp);
** ++cpp 是先取cpp 移動到下一個位置,然后再取值,cpp移動多少位置呢?是sizeof(char ***)的大小
cpp 移動 到下一個就是 c+2 所以 *++cpp 就是 "WORLD"
3、printf("%s\n",*--*++cpp+3);
這個就慢慢的顯得難度上來了,看這個東西總覺得怪怪的,我們還是分解一下, 首先?++cpp, cpp 是三級指針, 所以 *cpp 就是獲取二級指針的值因為之前已經對 cpp做了 ++運算,所以現在cpp 指向的是 cp[1],現在又對cpp 做++運算,所以 cpp就指向了 cp[2]了,--cpp 可以理解是對指針做運算,移動的值就是 sizeof (char *** ) 。
-- * ++cpp 就是*++cpp - sizeof(char ***) 也就是 &cp[2] - 8,這個操作之后,實際上就是 &cp[3]了,前面再加上一個?,就是cp[3]了,cp[3] +3 就是便宜3個值,也就是 "LO"?字符串了。
4、printf("%s\n",**cpp);
這個輸出 HELLO 應該沒有任何問題吧,原來題目沒有這個打印的,我是為了調試而已。
5、printf("%s\n",*cpp[-2]+3);
這個也是一個超級讓我們奇怪的表達式,我們可以主要看這個cpp[-2] ,cpp[-2] 可以這樣理解 cpp - 2*sizeof(char ***) = cpp - 2*8 = cpp -16
我們先理一下前面的運算,現在cpp在哪個位置?
這個很關鍵
我們之前對cpp 進行了兩次?++ 次操作,現在cpp 應該指向 cp[2]才對,使用gdb驗證試一下。
那*cpp[-2]?理論上應該是 cp[0]?的值,*cpp[2] +3 的輸出那應該很容易可以得出來了。就是?"HI"了。
6、printf("%s\n",cpp[-1][-1]+1);
我們知道,cpp[-1],就是當前的值往前偏移一個位置,跟上面的推斷一樣,當前cpp還是在cp[2]這個位置,所以cpp[-1]實際上就是cp[1]的位置,然后cpp[-1][0]就是 "WORLD"的位置,cpp[-1][-1]就是"WORLD"再往前偏移一個位置,就是"NEW"了。
后面再來一個+1?那輸出結果應該就是 "EW"了
至于最后的那個print("%s\n",*cpp),因為cpp是三級指針,這樣只取到二級指針,最終輸出的結果應該是不確定的。
熬夜寫完,也不能說完全正確,歡迎評論一起討論,如果覺得不錯,轉發支持一下,如果覺得不好意思轉發,點個在看讓我知道有人在看,謝謝。
掃碼或長按關注
總結
以上是生活随笔為你收集整理的C语言大神进来看看这个题目的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 工作流Activiti 6.x
- 下一篇: html5验证码制作,Html5生成验证