[英]Confusion about the output of this program
我是C編程新手,我目前正在學習數據類型修訂章節。 在下面的程序中,我的o / p是36,但編譯器顯示o / p 35。
main( )
{
char ch = 291 ;
printf ( "\n%d %c", ch, ch ) ;
}
任何人都可以解釋為什么o / p即將到來35? 我目前正在使用GCC 32位編譯器。
您的系統顯然具有8位char
類型。 這意味着291
太大而不適合 - 編譯器將其模數減少256(2 8 )並最終得到35。
在這種情況下, Clang提供了一個很好的警告:
example.c:3:11: warning: implicit conversion from 'int' to 'char' changes value
from 291 to 35 [-Wconstant-conversion]
char ch = 291 ;
~~ ^~~
您應該避免依賴此行為,因為它可能因實現而異。 C99和C11規范(第6.3.1.3節)說明有符號整數轉換:
否則,新類型將被簽名,並且值無法在其中表示; 結果是實現定義的,或者引發實現定義的信號。
由於您正在使用GCC,您可能有興趣閱讀文檔中的這段摘錄:
當該值無法在該類型的對象中表示時,將整數轉換為有符號整數類型的結果或信號(C90 6.2.1.2,C99 6.3.1.3) 。
為了轉換為寬度N的類型,該值以2 N為模減少到該類型的范圍內; 沒有信號被提出。
在那里你有對減少模256的完整解釋。
因為char
只能包含8位信息,而291需要的信息要多於要存儲的信息。 然后它將丟棄較高位並僅保留變量中的值。
您可以通過按位和模塊操作來模擬它:
291%256 = 35
291和0xFF = 35
8位字符可以包含-128到127或0到255的值,具體取決於其是有符號還是無符號。
你實際上是在溢出。 簽名字符只能在8位字符系統(幾乎無處不在)中從值-128到127(256值= 2 8 )。 所以我們選擇一個實際的字符,其值等於291%256 = 35。
不要忘記第一個字符是0而不是1。
這里實際上是如何使用2的補碼系統表示char:
unsigned
0 ------- 127 128 ------- 255
signed
0 ------- 127 -128 ------- -1
所以實際上signed char c1 = -128
等於unsigned char c2 = 128
但這里這個問題無關緊要。 我們討論的是模數,因為只考慮了最后8位(如果內存中只有8位可用,那么另一位會被存儲?)。
291 = % 1 0010 0011
( %
表示二進制表示)
它只保留% 0010 0011
等於35
,並且無論你是否接受它都將被視為完全相同。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.