這周開始做C語言筆試卷,什么嘛!考的都是概念,各種細節,雖然貌似書上都能找到,但我還真不清楚...頓時又有一種我C語言學的好渣的感覺 T_T
好了,說下在【上機實驗藍皮書背后,綜合測試題二】中難到的2道題,這兩道題使得你對【指針數組】和【數組指針】的區別更加清晰。
【例題1】
有以下程序:
1 #include <stdio.h> 2 3 int main() 4 { 5 char *s[] = {"one", "two", "three"}, *p; 6 p = s[1]; 7 printf("%c, %s\n",*(p+1), s[0]); 8 return 0; 9 }
執行后的結果是_______。
A. n, two B. w, one C. t, one D. o, two
第一次我選了 C,因為我以為 (p+1) 是指向 "three“ 的。這是對指針 p 類型的理解錯誤。
正確答案是 B,因為:
1 #include <stdio.h> 2 3 int main() 4 { 5 char *s[] = {"one", "two", "three"}; // s是一個指針數組,元素是3 6 // 個指向字符串常量的指針 7 char *p = s[1]; // p是一個指向字符串的指針變量 8 printf("%c, %s\n",*(p+1), s[0]); 9 // (p+1)是p的地址加一個字符內存的大小,從指向t變成指向w 10 return 0; 11 }
所以,平時我們說的指向字符串的指針,其實都是指向一個字符,所以對它進行位移運算時,加減都是1。
另外,如果你把第8行
printf("%c, %s\n",*(p+1), s[0]);
改成
printf("%c, %s\n",*(p+1), s[0]);
輸出就會是:wo,one
因為平時我們輸出字符串的時候,實際上都是把字符串的首地址傳給 printf( ) 函數,它通過末尾的 '\n',來判斷是否結束。
【例題2】
1 #include <stdio.h> 2 3 int main() 4 { 5 int a[3][4] = {{1,2,3,4}, {5,6,7,8}, {9,10,11,12}}; 6 int (*p)[4] = a; 7 printf("%d\n", *(*(p+1)+3)); 8 return 0; 9 }
以上代碼執行的結果是_______。
答案是 8
這道題初看我完全不理解...怎么*了還能*,(*p)[4]又是什么鬼...我做這份卷子前把【指針數組】和【數組指針】搞亂了=
是這樣的:
1.(*p)[4]:聲明p是一個指向(4個int元素的數組)的指針,因此 p+1 從指向 a[0],變成指向 a[1]
2.*(*(p+1)+3):為什么會有兩個星?
*(p+1) => a[1][0](也就是5),第一星從a[1]變成a[1][0],這個過程雖然地址沒有變,但指針的類型變了!原來指針+1是加4個 int,現在指針+1只加一個 int 了!!
*(p+1)+3 => a[1][3](也就是8),再取一個*就是從地址里讀出8
還可以修改一下原來的代碼弄清楚:
1 #include <stdio.h> 2 3 int main() 4 { 5 int a[3][4] = {{1,2,3,4}, {5,6,7,8}, {9,10,11,12}}; 6 int (*p)[4] = a; 7 printf("p: %p\n",p); 8 printf("p+1: %p\n",p+1); 9 printf("*(p+1): %p\n",*(p+1)); 10 printf("*(p+1)+3: %p\n",*(p+1)+3); 11 printf("%d\n",*(*(p+1)+3)); 12 return 0; 13 }
輸出的結果是:
p: 0x7fff9f4ba180 p+1: 0x7fff9f4ba190 *(p+1): 0x7fff9f4ba190 *(p+1)+3: 0x7fff9f4ba19c 8
好啦~