陣列變數與指標
阿新 • • 發佈:2018-12-06
背景:完全的C初學者。。試圖搞清楚陣列的概念,做了一些小試驗,查了一些解釋,合成此文。
我們說陣列變數相當於常量指標,那麼實際它就是常量指標名嗎?
簡單試驗:
1 #include <stdio.h> 2 3 int main() { 4 int a; //宣告int變數 5 printf("變數的地址:%p\n",&a); //宣告變數時,申請記憶體地址 6 printf("變數佔位:%d\n",sizeof(a)); //根據型別決定分配空間 7 // printf("變數的值:%d\n",a); //報錯,因為沒有放入值View Code8 a = 9; 9 printf("變數的值:%d\n\n",a); 10 11 12 int *p; //宣告指標變數 13 printf("指標變數的地址:%p\n",&p); 14 printf("指標變數佔位:%d\n",sizeof(p)); 15 // printf("指標變數指向:%d\n",*p); //報錯,因為沒有放入值 16 p = &a; 17 printf("指標變數的值:%p\n",p); 18 printf("指標變數指向:%d\n\n",*p); 19 2021 int s[4]={5}; //宣告陣列變數 22 printf("陣列變數的地址:%p\n",&s); 23 printf("陣列變數的地址+1:%p\n",&s+1); 24 printf("陣列變的地址佔位:%d\n",sizeof(&s)); //sizeof(地址) 25 printf("陣列變數的值:%p\n",s); //陣列變數的值的自己的地址!是一個特殊的指標! 26 printf("陣列變數的值+1:%p\n",s+1); 27 printf("陣列變佔位:%d\n",sizeof(s)); //sizeof(地址)?28 29 30 printf("陣列變數首元素的地址:%p\n",&s[0]); //s和s[0]地址相同! 31 printf("陣列變數次元素的地址:%p\n",&s[1]); //陣列是變數的容器 32 printf("取陣列首元素:%d\n",s[0]); 33 printf("對陣列變數解指標操作:%d\n",*s); //s指向的東西就是s[0]! 34 printf("陣列元素佔位:%d\n\n",sizeof(s[0])); 35 36 37 38 //指標變數和陣列變數互相s賦值 39 int b=88; 40 int *const p2=&b; //常量指標必須在宣告的時候初始化! 41 p = s; //可以改變指標p的值 42 // p2 = p; //常量指標不可修改! 43 // s = &b; //陣列變數不可修改! 44 int s2[5]; 45 printf("陣列變數s2的地址:%p\n",&s); 46 printf("陣列變數的值:%p\n",s); //地址相同?? 47 // s2 = s; //陣列變數不可修改! 48 49 return 0; 50 }
輸出:
可以看出來:
- 陣列變數符合指標的定義
- 陣列變數的值就是陣列首元素的地址
- 陣列變數不可修改,類似於常量指標
其中不解的是
- 用&取陣列變數的地址,發現與陣列首元素的值的地址相同,即s與&s的值相同。
- 如果陣列變數就是指標的話,那麼陣列變數的值為其首元素的地址,而它自己不應該放在另一個地址嗎?(就像上面的指標變數p一樣)
於是,查閱了一下,這個問題大致是這樣理解的
-
arr 本身是左值(但不可僅憑此表示式修改),指代陣列物件。不過 arr 會在大多數場合隱式轉換成右值表示式 &(arr[0]) 。為指標型別,指向 arr[0] 。
&arr 是右值表示式,為指標型別,指向 arr 本身。簡單來說就是 arr 本身不是地址而是指代整個陣列,只不過會隱式轉成指標罷了。arr (轉換後)和 &arr 型別不同,數值相等是因為 arr 和 arr[0] 地址相同,這裡地址指首地址。【轉自知乎-暮無井見鈴】
另有一份總結:
- 陣列地址與陣列名:
- 陣列名代表陣列首元素的地址(a);
- 陣列的地址需要用取地址符&才能得到(&a);
- 陣列首元素的地址值與陣列的地址值相同
- 陣列首元素的地址與陣列的地址是兩個不同的概念
- 陣列名的盲點:
- 陣列名可以看做一個常量指標;
- 陣列名“指向”的是記憶體中陣列首元素的起始位置;
- 在表示式中陣列名只能作為右值使用下
- 下列場合中陣列名不能看做常量指標:
- 陣列名作為sizeof操作符的引數;
- 陣列名作為&運算子的引數
驗證s與&s類別不同:
s與&s值相同,但s+1與&s+1值不同