2011-05-26 34 views
0
#include<stdio.h> 

int main() 
{ 
    int i = 10; 
    int *p = &i; 

    printf("\n address of initialized pointer p: %u \n", p); 
    p = &(*p); 
    printf("\n modified address of initialized pointer p:%u value:%d valuez address: %d \n", p, *p, &(*p)); 

    return 0; 
} 

代碼輸出: -澄清過左值,在C的指針的右值行爲

初始化指針p的地址:3221221820

初始化指針p的修改地址:3221221820值:10 valuez地址: -1073745476

爲什麼「&(* p)」,在賦值語句和printf語句中的行爲不同?

更新 對不起,只是格式說明符錯誤在printf;)。謝謝你的回覆和指出。

回答

4

您在printf中使用了不正確的格式說明符。使用%d打印地址將不起作用。相反使用%p。 [%u對於打印地址也是不正確的。]

This按預期工作。

+0

它在%p和%u之間有什麼不同? – Hemanth 2011-05-26 12:17:01

+0

'%u'用於打印無符號整數,'%p'用於指針。 – 2011-05-26 12:17:54

+0

感謝Prasoon,還有一個疑問,當我使用%p我得到0x7fbffff1bc,但是當我將由%u - 3221221820打印的值轉換爲十六進制時,我只得到bffff1bc。那麼當我使用%p時,附加的額外0x7f是什麼? – Hemanth 2011-05-26 12:19:59

1

指針的標準格式說明符是%p。爲了安全起見,您應該在撥打printf時明確地將指針投射到(void*)。任何其他格式說明符不保證與指針值一起使用。

例如

printf("p: %p; *p: %d; &(*p): %p \n", (void*)p, *p, (void*)&(*p)); 

你看到的差別只是在於,所述第一格式指定符是%u打印出指針的值作爲無符號整數並且正在使用%d它打印它作爲一個帶符號的整數的第二次。

+0

如果該值已經是一個指針,那麼將它轉換爲「void * '做?我可以看到它留在C++中的問題(繼承和運算符重載可能會導致問題),但是什麼使它在C中很危險? – cHao 2011-05-26 12:20:12

+0

@cHao:雖然不常見,但指向不同類型的指針可以在C中具有不同的表示形式。'%p'格式說明符要求相應的參數具有「指向void類型的指針」類型,所以如果您擁有的變量是指向其他的東西,然後嚴格地說,你需要將其轉換爲符合'printf'的要求。 – 2011-05-26 12:25:15

1

你有

%d而不是%u當你要打印的地址第二次。

注以粗體顯示的變化在下面的修改的源:%U值:: 初始化指針p的

的printf(「\ n改性地址%d valuez地址:%U \ n 「,p,* p, &(* p));

最值得注意的是,如another answer on this thread中已經指出的那樣,最應該使用%p來打印指針值而不是%u。