簡體   English   中英

指針的地址和從指針轉換的int值有什么區別

[英]What is the difference between pointer's address and the int value converted from pointer

我認為ptr的地址和a的地址彼此相同。 而且我還認為ptr的地址與從指針轉換的int值相同。

但是控制台的結果拒絕了我,這是什么原因? 我如何理解結果。

#include <stdio.h>

int main() {
    int a[5] = {1, 2, 3, 4, 5};
    int *ptr = (int *) ((int) a);

    printf("a's address: %p \n", a);
    printf("ptr's address: %p \n", ptr);
    printf("ptr's int value: %x", (int)ptr);

    return 0;
}

控制台的結果是

a's address: 0x7ffee8d30600 
ptr's address: 0xffffffffe8d30600 
ptr's int value: e8d30600

PS

我已經編輯了標題,並且原始的模棱兩可的標題是“指針的地址和指針的int值之間有什么區別”

並不是您要在這里實現的目標。 一個int僅包含32位值。 因此,(int)ptr將僅返回ptr地址的32位值,即您獲得的低4個字節。

C具有uintptr_t ,可讓您存儲指針值:

void *p = …;
uintptr_t u = (uintptr_t)p;
void *q = (void *)q;
// here q is equivalent to p

在許多平台上, up一樣存儲p指向的對象的地址,並且up在內存中具有相同的表示形式。 這不是義務:允許C實現使用不同的表示形式。 但是使用相同的表示形式是滿足C標准要求的最明顯方法。

請注意,如果從仍然有效的指針獲得uintptr_t值,則從uintptr_t為指針類型只會提供可用的指針。 這可能是微妙的。 即使在表示形式相同的處理器體系結構上(幾乎都是它們),編譯器也可以假定您並沒有做太多瘋狂的事情,並相應地進行了優化。 有關一些示例,請參見對Cerberus調查的答復

在您的情況下,您沒有嘗試將指針值存儲在uintptr_t ,而是試圖將其存儲在int 這失敗了,因為在您的平台上, int太小,無法存儲指針值。 顯然,在您的平台上,指針是64位值,而int是32位值。 這是非常常見的安排。

  • a是數組的地址。 (這是指向數組第一個元素的指針,並且在您的平台上,指針僅由地址表示。)。 在此特定運行中,它是0x7ffee8d30600。 那里沒什么特別的。
  • (int) a地址轉換a到一個int值。 這是實現定義的。 您的實現執行通常的事情:由於int太小,它會截斷該值。 將上述地址截斷為無符號的32位值將產生0xe8d30600 為了獲得帶符號的值,最高有效位變為符號位,因此a恰好是負數: a-388823552
  • p(int *) ((int) a) 再次由實現定義此轉換,並且您的實現又執行與大多數操作相同的操作。 它以32位帶符號int-388823552 ,它延伸到所需的寬度和它移位到無符號范圍,產生2 64 - 388823552 = 0xffffffffe8d30600。
  • (int)p應用與上述(int)a相同的截斷過程,並再次產生-388823552 但是,你正在使用的%x說明符打印出來,所以這個值轉換為unsigned ,賦予值2 32(32-bit類型平台) - 388823552 = 0xe8d30600。

我明白了 機器基於64位地址。 將地址轉換為int值將丟失地址的高位值。 因此,此處a的地址與ptr的地址不同。

如果要在C ++中使用指針,我們可以使用intptr_t或最好使用uintptr_t

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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