C語言中的 *p[2] 與 (*p)[2] 的大相徑庭


C語言運算符優先級表(由上至下, 優先級依次遞減)html

運算符 結合性
()  []  ->  . 自左向右
 !  ~  ++  --  -  (type)  *  &  sizeof 自右至左
*  /  %  自左向右
+  -  自左向右
<<  >>  自左向右
<  <=  >  >=  自左向右
==  !=  自左向右
自左向右
自左向右
自左向右
&&  自左向右
||  自左向右
?:  自右至左
assignments  自右至左 
自左向右

 (來自C陷阱與缺陷)數組


 


 

對於( )  或者  [ ] 的優先級是最高的函數

因而對於  *p[2]  結合的方式應該是   *(p[2])    對於  (*p)[2]  顯然結合方式是括號中的 *p 優先於 [2]spa

具體指針

char *p[2]  表示p是一個存儲指向char類型數據的指針的數組code

char (*p)[2]  則表示*p是一個擁有兩個char類型元素的數組,那麼p則表示指向這個數組的指針htm

void test(){ char *p1[2]; char (*p2)[2]; printf("p1----%d\n", sizeof(p1)); printf("p2----%d\n", sizeof(p2)); return; }

獲得的結果是blog

能夠看到p1表示的是一個擁有兩個(char *)類型的數組,一個指針佔有4個字節,倆個固然是8個字節內存

而p2僅僅就只是一個指針,只佔有4個字節字符串

經常使用用途


  • 對於  *p[]

在main函數的參數中有使用到,其中的 char *argv[]的argv就是一個指針數組,用來存儲函數調用時傳進來可變個數的參數

(詳細:利用 gdb 探究main(int argc, char *argv[]){} 中的char *argv[]

int main(int argc, char *argv[]) { something you want to do; return 0; }

好比能夠這樣

char *pp[2] = {"hello", "world",};

pp[0]存儲字符串"hello"的第一個字符的地址,pp[1] 存儲字符串"world"的第一個字符的地址

printf("%s\n", pp[0]);

將會打印出 hello


  • 對於  (*p)[]

無疑就是能夠做爲二維數組的引用

其實二維數組的本質也是一維數組,那麼當咱們定義一個二維數組的時候爲何不能夠使用像引用一維數組的那樣的指針來引用二維數組呢?

錯誤樣例

void arrays(){ int nums[3][4] = {0}; int *pn = nums; }

緣由就是二維數組其實就是一個成員是一維數組的一維數組,因此它的類型是應該是數組類型

而這裏的pn所指的類型是int,就會出現類型不匹配的問題

正確的方式是

void arrays(){ int nums[3][4] = {0}; int (*p_nums)[4] = nums; }

這樣的p_num是指向類型爲數組的指針,與nums的類型相匹配


補充

二維數組在內存中的存儲問題

示例代碼

#include <stdio.h> #include <stdlib.h>

int main() { /*定義char類型便於觀察地址,由於char只佔一個byte*/
    char chars[3][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12},}; printf("-------------------------------------------------------------------\n\n"); for(int i = 0; i < 3; ++i){ for(int j = 0; j < 4; ++j){ printf("%5d(%d)", chars[i][j], (int)&chars[i][j]); } printf("\n"); } printf("\n-------------------------------------------------------------------\n"); printf("%d\n", sizeof(chars)); printf("%d\n", (int)chars); printf("%d\n", (int)(chars + 1));/*移動了4個元素,行移動*/ printf("-------------------------------------------------------------------\n"); printf("%d\n", sizeof(chars[0])); /*能夠看做是一維數組的第一個元素的地址 形如 一維數組中的 &array[0]*/ printf("%d\n", (int)&chars[0]); /*能夠看做就是一維數組裏的第一個元素是數組,它至關於一個數組名錶示數組地址 形如 array*/ printf("%d\n", (int)chars[0]); printf("-------------------------------------------------------------------\n"); return 0; }

輸出

獲得的結果以及代碼註釋已經能夠說明一些問題了,就再也不重複


本節完...... 

相關文章
相關標籤/搜索