2017-10-12 48 views
0

我試着玩一些指針來指向'i'的指針,我發現有兩個不同的地址分配給聲明%u和%lu,%llu。怎麼可能是一個變量可以在執行相同的實例有兩個不同的地址 -變量如何在同一時間點有兩個不同的地址?

#include <stdio.h> 
int main(void) 
{ 
    int i; 
    float f; 
printf("\nEnter an integer:\t"); 
scanf("%d",&i); 

    printf("\nValue of address of i=%u",&i); 
    printf("\nvalue of address of i=%d",&i); 
    printf("\nValue of address of i=%lu",&i); 
    printf("\nValue of address of i=%llu",&i); 

    printf("\nvalue of i=%d",i); 
    printf("\nvalue of i=%u",i); 
    printf("\nvalue of i=%lu",i); 
    printf("\nvalue of i=%llu\n",i); 

} 

這是輸出 -

[email protected]:~/Desktop/Daily programs/pointers$ ./pointer001 

    Enter an integer: 12 

    Value of address of i=1193639268 
    value of address of i=1193639268 
    Value of address of i=140725797092708 
    Value of address of i=140725797092708 
    value of i=12 
    value of i=12 
    value of i=12 
    value of i=12 

在這裏,我們可以清楚地看到,%u和%d的地址是1193639268(儘管%d和%u的輸出在所有情況下可能不相等),%lu和%llu的輸出是140725797092708,它的物理意義是什麼。

回答

6

正確格式說明用於打印指針是%p

使用錯誤的格式說明,如%d%u%lu,或%llu調用undefined behavior

正如你所看到的具體行爲,您的具體實施指針可能是一個8字節的值,而一個intunsigned int可能是一個4字節的值。因此,使用%d%u只讀取傳入該函數的8字節值的前4個字節並打印該值。當您使用%lu%llu時,所有8個字節都會被讀取並打印。

再次,因爲你調用未定義行爲,你不能依賴於這個特定的輸出是一致的。例如,在32位模式和64位模式下編譯可能會產生不同的結果。最好使用%p,並且將指針投射到void *,因爲這是%p預期的特定指針類型。

+2

細節:用於打印'void *'指針的適當格式說明符是'「%p」'。 ''%p「'可能不適用於'int *',但常見。 – chux

+1

@chux好點。我已經添加了這個細節 – dbush

2

它沒有。這只是你使用不正確的格式說明符指針類型。

上這樣做的行爲是不確定的。您觀察到的輸出是未定義行爲的表現。

使用%p一個指針,轉換指針參數一個const void *的類型(許多編譯器都在這最後一點鬆懈,但它是很好的做法仍然)。

3

您使用了錯誤的格式說明,這會導致undefined behavior。在這種特殊情況下的行爲是1193639268(0x47257D64)是140725797092708(0x7FFD47257D64)下部

正確的格式說明符的地址是%p

4

只有一個地址。您正在使用不同寬度的整數打印代碼,所以有時您會看到32位地址,有時您會看到64位地址。多少有效取決於您的系統;在32位系統上,打印64位意味着該值的32位是垃圾;在64位系統上,打印32位意味着你省略了一半的指針。

有一個專用的格式代碼,%p了一種旨在用於打印指針,使用,非整打碼。

相關問題