#include<stdio.h>
void main()
{
int n = 2;
printf("%c",&n);
}
輸出:L試圖瞭解printf的一個指針有一個char說明符(%C)
在使用%d
它當然給出可變n
的地址,但它爲什麼使用%c
輸出L&
#include<stdio.h>
void main()
{
int n = 2;
printf("%c",&n);
}
輸出:L試圖瞭解printf的一個指針有一個char說明符(%C)
在使用%d
它當然給出可變n
的地址,但它爲什麼使用%c
輸出L&
這是因爲您告訴printf()函數將int n的地址的前1個字節顯示爲char。
它是未定義的行爲因爲您已經使用了錯誤的格式說明符。
C11標準:7.21.6.1:第9段:
如果轉換規格是無效,該行爲是 未定義。如果任何參數不是相應轉換規範的正確類型,則行爲是undefined。
這意味着如果使用錯誤的格式說明符調用printf
會發生任何事情。
由於rsp的其他answer表示行爲未定義,任何事情都可能發生。
在你的情況會發生以下情況:
它讀取的&n
一個字節,因爲一個字符是一個字節大小其中大部分是8位長的,看到CHAR_BIT
explanation on SO。然後它將它打印爲字符。
如果您的機器上的int*
和int
類型相同,則該字節可能是&n
的第一個字節。這意味着您的變量n
位於地址0x48...
(big-endian)或0x...48
(little-endian),因爲0x48
是H
的Ascci code。我假設你的程序正在使用Ascii進行編碼,但這不一定非要。
(您改變了角色從H
到L
但我離開這個答案,因爲它是。)
此外該字節可以在&n
中間的某處如果int*
超過你的系統的int
的大小。
你應該在GCC例如-Wall
使更多的警告編譯,您將獲得:
警告:格式「%C」需要類型「詮釋」的說法,但參數2的類型爲「廉政* '[-Wformat =]
在這種情況下你施放該值到char
的行爲將被明確限定,但是依賴於實現作爲指針類型的鑄造爲整數被定義實現。
儘管如此,你在做什麼也沒有意義,它不會做的演員。
還有一些不精確的地方(這很容易引發UB):1.)ascii沒有強制要求2.)char'總是**一個字節,但一個字節可能有多於8位3)使用轉換,它不是未定義的,但仍然不是特別有用,因爲指針轉換爲整數類型的結果是*實現定義的* - 仍然是upvoted,解釋是有幫助的! –
@FelixPalmen:謝謝你的解釋! –
答案假設'int'和'int *'是相同的大小,並且'int'和'int *'通過相同的機制傳遞給'printf()'。在C. – chux
因爲指針不是字符,所以這段代碼是**未定義的行爲**。它也可以做其他任何事情。這是對你的特定環境的一種隨機效應,當printf()的一個指針的一部分在嘗試獲得一個字符轉換爲H時將會評估它... –
我可以聞到UB。唯一發生的事情是UB。 –
呵呵,所以**現在**它*突然*「L」?你覺得現在有什麼不完美嗎? –