4.3.2,a 和&a 的區別

 

 

4.3.2,a 和&a 的區別
通過上面的分析,相信你已經明白數組和指針的訪問方式了,下面再看這個例子:
main()
{
 int a[5]={1,2,3,4,5};
 int *ptr=(int *)(&a+1);
 printf("%d,%d",*(a+1),*(ptr-1));
}

打印出來的值爲多少呢? 這裏主要是考查關於指針加減操作的理解。
對指針進行加1 操作,得到的是下一個元素的地址,而不是原有地址值直接加1。所以,
一個類型爲T 的指針的移動,以sizeof(T) 爲移動單位。因此,對上題來說,a 是一個一
維數組,數組中有5 個元素; ptr 是一個int 型的指針。
&a + 1: 取數組a 的首地址,該地址的值加上sizeof(a) 的值,即&a + 5*sizeof(int),也
就是下一個數組的首地址,顯然當前指針已經越過了數組的界限。
(int *)(&a+1): 則是把上一步計算出來的地址,強制轉換爲int * 類型,賦值給ptr。
*(a+1): a,&a 的值是一樣的,但意思不一樣,a 是數組首元素的首地址,也就是a[0]的
首地址,&a 是數組的首地址,a+1 是數組下一元素的首地址,即a[1]的首地址,&a+1 是下一
個數組的首地址。所以輸出2
*(ptr-1): 因爲ptr 是指向a[5],並且ptr 是int * 類型,所以*(ptr-1) 是指向a[4] ,
輸出5。
這些分析我相信大家都能理解,但是在授課時,學生向我提出瞭如下問題:
在Visual C++6.0 的Watch 窗口中&a+1 的值怎麼會是(x0012ff6d(0x0012ff6c+1)呢?
/*
剖析
A       是數組首元素的首地址,  a+1 是下一個元素
&a[0]   是數組首元素的首地址,                  
&a      數組的首地址            a+1 是下一個數組
*/
C 語言引入一個術語-----“可修改的左值”。  A[10];
意思就是,出現在賦值符左邊的符號所代表的地址上的內容一定是可以被修改的。換句話說,就是我們只能給非只讀變量賦值。既然已經明白左值和右值的區別,下面就討論一下數組作爲左值和右值的情況:
當a 作爲右值的時候代表的是什麼意思呢?
很多書認爲是數組的首地址,其實這是非常錯誤的。
a 作爲右值時其意義與&a[0]是一樣,代表的是數組首元素的首地址,而不是數組的首地址。這是兩碼事。

但是注意,這僅僅是代表,並沒有一個地方(這只是簡單的這麼認爲,其具體實現細節不作過多討論)來存儲這個地址,也就是說編譯器並沒有爲數組a分配一塊內存來存其地址,這一點就與指針有很大的差別。
a 作爲右值,我們清楚了其含義,那作爲左值呢?a 不能作爲左值!
這個錯誤幾乎每一個學生都犯過。編譯器會認爲數組名作爲左值代表的意思是a 的首元素的首地址,但是這個地址開始的一塊內存是一個總體,我們只能訪問數組的某個元素而無法把數組當一個總體進行訪問。所以我們可以把a[i]當左值,而無法把a當左值。其實我們完全可以把a 當一個普通的變量來看,只不過這個變量內部分爲很多小塊,我們只能通過分別訪問這些小塊來達到訪問整個變量a 的目的。


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章