C語言的數組名和對數組名取地址


相信不少的C語言初學者都知道,數組名相當於指針,指向數組的首地址,而函數名相當於函數指針,指向函數的入口地址。現在又這樣一個問題,如果對數組名取地址,那得到的會是什么呢?很多人立刻會想到:給指針取地址,就是指針的指針,既二級指針嘛!當然這樣的結論是錯誤的,不然這篇筆記也就沒有意義了。


下面我們來逐步分析,下面是一段驗證這個問題的代碼

Code:
  1. #include<stdio.h>   
  2. int main()   
  3. {   
  4.     int a[10];   
  5.   
  6.     printf("a:/t%p/n", a);            
  7.     printf("&a:/t%p/n", &a);          
  8.     printf("a+1:/t%p/n", a+1);        
  9.     printf("&a+1:/t%p/n", &a+1);     
  10.   
  11.     return 0;   
  12. }  

 

大家可以編譯運行一下,我的輸出的結果是:

Code:
  1. /*   
  2. a:          0012FF20  
  3. &a:         0012FF20  
  4. a+1:        0012FF24  
  5. &a+1:       0012FF48  
  6. */  

a和&a指向的是同一塊地址,但他們+1后的效果不同,a+1是一個元素的內存大小(增加4),而&a+1增加的是整個數組的內存大小(增加40)。既a和&a的指向和&a[0]是相同的,但性質不同!

讀到這里,有很多朋友已經明白其中的機制了,如果還是有些模糊,請繼續往下看

Code:
  1. int main()   
  2. {   
  3.     int a[10];   
  4.     printf("%d/n",sizeof(a));   
  5.     return 0;   
  6. }  

這段代碼會輸出整個數組的內存大小,而不是首元素的大小,由此我們是否聯系到,sizeof(a)這里的a和
&a有些相同之處呢?!  是的,沒錯,&a取都得是整個數組的地址!既數組名取地址等價於對數組取地址。


好了,讓我們總結一下,如果你還是不太理解,不用擔心,下面的概念很清晰


其實a和 &a結果都是數組的首地址,但他們的類型是不一樣。
a表示&a[0],也即對數組首元素取地址,a+1表示首地址+sizeof(元素類型)。
&a雖然值為數組首元素地址,但類型為:類型 (*)[數組元素個數],所以&a+1大小為:首地址+sizeof(a)。

還有這篇文章最初提到的指針的指針的那個錯誤結論,其實即使不懂上述內容,也應該判斷出結論是錯誤的,大家應該在了解數組名即是數組的首地址的同時,也要知道,數組名僅僅是“相當”於指針,而並非真的是指針,數組名是只是個常量(一個值為數組首元素地址的常量),所以不能進行++或者--運算。而常量更是無法取地址的,而之所以有&a,其實這里的a的意義早已經不是當初那個數組名了,它此時代表了整個數組。

結論2:數組作為左值和數組作為右值時的區別造成了無數人的困惑與誤解:foo 作為右值時確實等價於一個指針,因為數組無法像普通對象那樣返回它的值,它的元素可能有成百上千個,但作為一個左值時——比如作為取地址操作符的操作數時,數組就是作為一個數組對象而出現的,而不是指針,取地址返回一個指向數組的指針,而不是指向指針的指針。
一句話總結就是:數組就是數組,有着自己的特性。
(題外話:從生成的匯編語言看,用指針來訪問內存實際上並不比使用數組來訪問內存快,反而是慢了)
轉載請注明來源 http://blog.csdn.net/imred/article/details/45441457


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM