數組變量與指針

背景:徹底的C初學者。。試圖搞清楚數組的概念,作了一些小試驗,查了一些解釋,合成此文。數組

咱們說數組變量至關於常量指針,那麼實際它就是常量指針名嗎?ide

簡單試驗:spa

 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);  //報錯,由於沒有放入值
 8     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     
20     
21     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 }
View Code

輸出:3d

能夠看出來:指針

  • 數組變量符合指針的定義
  • 數組變量的值就是數組首元素的地址
  • 數組變量不可修改,相似於常量指針

其中不解的是code

  • 用&取數組變量的地址,發現與數組首元素的值的地址相同,即s與&s的值相同。
  • 若是數組變量就是指針的話,那麼數組變量的值爲其首元素的地址,而它本身不該該放在另外一個地址嗎?(就像上面的指針變量p同樣)

因而,查閱了一下,這個問題大體是這樣理解的對象

  • arr 自己是左值(但不可僅憑此表達式修改),指代數組對象。不過 arr 會在大多數場合隱式轉換成右值表達式 &(arr[0]) 。爲指針類型,指向 arr[0] 。
    &arr 是右值表達式,爲指針類型,指向 arr 自己。簡單來講就是 arr 自己不是地址而是指代整個數組,只不過會隱式轉成指針罷了arr (轉換後)和 &arr 類型不一樣數值相等是由於 arr 和 arr[0] 地址相同,這裏地址指首地址。C做爲實用語言,爲了使用方便而進行隱式類型轉換。【參考知乎-暮無井見鈴blog

  • &arr[0]&arr相同是合理的,而arr的值也跟前面兩個相同,這更像是強加的語言規定,或者說……語法糖。【參考

另有一份總結:內存

  • 數組地址與數組名:
    • 數組名錶明數組首元素的地址(a);
    • 數組的地址須要用取地址符&才能獲得(&a);
    • 數組首元素的地址值與數組的地址值相同
    • 數組首元素的地址數組的地址兩個不一樣的概念
  • 數組名的盲點:
    • 數組名能夠看作一個常量指針;【能夠轉換爲,執行指針的操做】
    • 數組名「指向」的是內存中數組首元素的起始位置;
    • 在表達式中數組名只能做爲右值使用下
  • 下列場合中數組名不能看作常量指針
    • 數組名做爲sizeof操做符的參數;【sizeof只作類型推測,不進行計算,所以數組變量不會被轉換爲指針變量,說明數組變量自己不是指針,可驗證sizeof(arr)和sizeof(arr[0]),兩者是不一樣的】
    • 數組名做爲&運算符的參數;【可驗證以下】

    

驗證s與&s類別不一樣get

  s與&s值相同,但s+1與&s+1值不一樣

相關文章
相關標籤/搜索