[英]C array address confusion
假設我們有以下代碼:
int main(){
int a[3]={1,2,3};
printf(" E: 0x%x\n", a);
printf(" &E[2]: 0x%x\n", &a[2]);
printf("&E[2]-E: 0x%x\n", &a[2] - a);
return 1;
}
編譯並運行時,結果如下:
E: 0xbf8231f8
&E[2]: 0xbf823200
&E[2]-E: 0x2
我理解&E [2]的結果是8加上數組的地址,因為索引為2並且類型為int(我的32位系統上是4個字節),但我無法弄清楚為什么最后一行是2而不是8?
另外,最后一行應該是什么類型 - 整數或整數指針?
我想知道是不是這種怪癖的C型系統(有點鑄造)?
你必須記住a[2]
真正含義。 它完全等同於*(a+2)
。 這么多,寫2[a]
代替完全合法,效果相同。
為了使其有效並且有意義,指針算法會考慮指向的事物的類型。 但這在幕后得到了解決。 您只需在陣列中使用自然偏移,所有細節都可以解決。
相同的邏輯適用於指針差異,這解釋了您的結果2
。
在引擎蓋下,在您的示例中,索引乘以sizeof(int)
以獲取字節偏移量,該偏移量將添加到數組的基址中。 您在兩個地址打印中公開該細節。
當減去相同類型的指針時,結果是元素數而不是字節數。 這是設計使您可以輕松索引任何類型的數組。 如果你想要字節數 - 將地址轉換為char *。
當您將指針遞增1(p + 1)時,通過將(p + sizeof(Type))個字節添加到p,指針將指向下一個有效地址。 (如果Type為int,則p + sizeof(int))
類似的邏輯也適用於p-1(當然在這種情況下減去)。
如果你只是在這里應用這些原則:
簡單來說:
a[2] can be represented as (a+2)
a[2]-a ==> (a+2) - (a) ==> 2
所以,在幕后,
a[2] - a[0]
==> {(a+ (2* sizeof(int)) ) - (a+0) } / sizeof(int)
==> 2 * sizeof(int) / sizeof(int) ==> 2
線&E [2] -2正在進行指針減法,而不是整數減法。 指針減法(當兩個指針指向相同類型的數據時)返回地址的差值除以它們指向的類型的大小。 返回值是一個int。
要回答“更新”問題,再次執行指針算術(此時指針添加)。 它在C中以這種方式完成,以便更容易“索引”指針指向的一大塊連續數據。
您可能對Pointer Arithmetic In C的問題和答案感興趣。
基本上,+和 - 運算符在指針上使用時會考慮元素大小。
在C中添加和減去指針時,使用數據類型的大小而不是絕對地址。
如果你有一個int指針並向其添加數字2,它將前進2 * sizeof(int)。 以同樣的方式,如果你減去兩個int指針,你將得到sizeof(int)單位的結果,而不是絕對地址的差異。
(使用數據類型大小的指針非常方便,因此您可以簡單地使用p++
而不必每次都指定類型的大小: p+=sizeof(int)
。)
Re:“另外,最后一行的類型應該是什么?一個整數,還是一個整數指針?”
整數/數字。 同樣的道理:今天 - 4月1日=數字。 不是約會
如果要查看字節差異,則必須使用大小為1字節的類型,如下所示:
printf("&E[2]-E:\t0x%x\n",(char*)(&a[2])-(char*)(&a[0]))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.