簡體   English   中英

關於這個計划的輸出的困惑

[英]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.

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