簡體   English   中英

C數組地址混亂

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM