數組和指針的區別

目錄(?)[+]

發現好多人搞不清楚數組和指針的區別。

數組申明時編譯器自動分配一片連續的內存空間

指針申明時只分配了用於容納指針的4字節空間

作爲函數參數時,數組參數和指針參數等價

數組名在多數情況下可視爲常量指針,其值不能改變

指針的本質是變量,保存的值被看做內存中的地址。

名字上的區別:

數組名通常情況下被作爲常量指針,只能作爲左值出現,
對於數組 
  1. int a[5];  
  2. a和&的意義不同,a是數組元素的首地址,&a是整個數組的地址  
看下面程序
  1. #include <stdio.h>  
  2.   
  3.   
  4. int main()  
  5. {  
  6.     int a[5] = {1,2,3,4,5};  
  7.     int *p1 = (int *)(&a + 1);  
  8.     int *p2 = (int *)(a + 1);  
  9.     printf("p1[-1] = %d\n",p1[-1]);<span style="white-space:pre">           </span>//5  
  10.     printf("p2[-1] = %d\n",p2[-1]);<span style="white-space:pre">           </span>//1  
  11. }  
複製上的區別:
前面說了數組名一般只能作爲左值出現,所以復值的時候只能一個一個來,而指針,則可直接進行
  1. <span style="white-space:pre">  </span>int a1[5] = {1,2,3,4,5};  
  2.     int a2[5];  
  3.     a2 = a1;    //oOps  
  4.     for(int i = 0;i < 5;i++)  
  5.     {  
  6.         a2[i] = a1[i];      //*a2++ == *a1++  
  7.     }  
  8.     char *p1 = "hello";  
  9.     char *p2 = NULL;  
  10.     p2 = p1;                //正確,p2也指向了hello所在內存空間   

計算內存空間大小的區別:
計算數組所佔內存大小使用sizeof這個關鍵字,而計算字符串使用size_t strlen(const char *s);函數,這裏是好多人常出現錯誤的地方,不少人計算數組長度喜歡用strlen看下面例子
  1. <span style="white-space:pre">  </span>char s1[] = {'a','\0','c','c'};  
  2.     int s2[] = {0,1,2,3,4,5,6,7,8};  
  3.     printf("%d\n",strlen(s1));  
  4.     printf("%d\n",strlen(s2));  
上面兩個均不能的到正確結果,究其原因還得探究size_t strlen(const char *s);的實現。
  1. size_t strlen(const char *str)  
  2. {  
  3.     int len = 0;  
  4.        assert(str != NULL);  
  5.        while(*str != '\0')  
  6.        {  
  7.               len++;  
  8.        }  
  9.        return len;  
  10. }  

看了原型大家都知道上面的結果是怎麼來的了。再次強調求數組所佔內存空間用sizeof關鍵字。
字符串數組和字符數組:
  1.   char s1[] = {'h','e','l','l','o'};  
  2. char s2[] = "hello";  
  3. printf("%d\n",sizeof(s1));  
  4. printf("%d\n",sizeof(s2));<span style="white-space:pre">        </span>//printf("%d\n",strlen(s2));結果是6  

結果分別是4和5,在C中並沒有字符串數據類型,只是用字符數組進行模擬,在最後以‘\0’結束;
字符串數組和字符串:
  1.    char s1[] = "hello";  
  2. char *s2 = "hello";  
  3. s1[1] = 'H';          
  4. s2[1] = 'H';    //oOps  

這裏主要是有個存儲位置的問題。s2指向的一個字符串字面量,存在在只讀代碼段,其值不能被修改,s1是字符串數組存在棧空間。
作爲形參傳遞:
數組名作爲形參傳遞的時候是有退化的
  1. void fun(int a[5]) <==> void fun(int a[]) <==>  void fun(int *a)  

所以在傳遞數組的時候還需要另一個參數,指示數組大小。其他情況
  1. void fun(int *a[5]) <==> void fun(int *a[]) <==>    void fun(int **a)  
  2.      void fun(int a[5][6]) <==> void fun(int a[][6]) <==>   void fun(int (*a)[6])  
三維或更多維數組無法使用
定義數組使用爲指針,定義爲指針,使用爲數組:
定義爲數組使用爲指針:
  1. //b.c  
  2. #include <stdio.h>  
  3. char str[] = "hello";  
  4. //a.c  
  5. #include <stdio.h>  
  6.   
  7. extern char *str;  
  8. int main()  
  9. {     
  10.     printf("%s",str);   //oOps,正解printf("%s",(char *)&str);  
  11.     return 0;  
  12. }  
定義爲指針使用爲數組
  1. //b.c  
  2. #include <stdio.h>  
  3.   
  4. char *str = "hello";  
  5.   
  6. //a.c  
  7.   
  8. #include <stdio.h>  
  9.   
  10. extern char str[];  
  11. int main()  
  12. {     
  13.     printf("%s",str);//輸出什麼?正解:printf("%s",(char *)(*(unsigned int *)str));  
  14.     return 0;  
  15. }  
這兩個的形成原因是由於對數組和指針的處理方式不同(指針是間接的,數組是直接的)。
引用:http://blog.csdn.net/z1179675084/article/details/12951323
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章