2014-11-21 22 views
3

C中的無符號int的大小爲0 to 65,535 or 0 to 4,294,967,295C中的無符號整數的行爲

我用下面的代碼在C下測試:

unsigned int number = 0; 
number -= 300; 
printf("%d\n", number); 

OUTPUT:-300

記得,如果unsigned int變量的值低於0,但應迴繞,我期待輸出結果如4294966996。但是從控制檯打印的輸出是-300

我在C++中測試了類似的語句,它確實給了我4294966996

我的問題是:爲什麼輸出-300,儘管它是一個unsigned int


PS:我已經通過幾個職位有類似的標題看,但他們都沒有解決同一個問題:

signed vs unsigned int in C

Unexpected results on difference of unsigned ints

+2

'printf'是一個愚蠢的函數。你必須確保你傳遞它期望的類型! – 2014-11-21 07:14:52

+1

請記住用signed int格式字符串打印unsigned int是未定義的行爲。 – 2014-11-21 07:15:04

+0

只是最後一個問題:我是否正確地說,如果我使用%d打印它,它會在打印之前將其隱式轉換爲已簽名? – user3437460 2014-11-21 07:17:01

回答

8

因爲printf("%d\n", number);將打印有符號值即使參數是無符號的。使用printf("%u\n", number);可以正確打印無符號值。

2

僅僅是@ UniCell出色的答案背景。

硬件以完全相同的方式存儲intunsigned int。沒有不同。如果你開始增加或減少它們,它們將以完全相同的方式溢出和下溢。

0xFFFFFFFF + 1 = 0 
0 - 1 = 0xFFFFFFFF 

如果我們考慮的結果爲無符號,0xFFFFFFFF意味着4,294,967,295,否則就意味着-1。它被稱爲2的補碼存儲。加和減是符號不可知的。但乘法和除法不是,所以通常有不同的簽名和未簽名的機器指令。

這些變量的類型只有編譯器而已,而不是運行時。 printf的參數可以是任何類型,並且傳遞的變量在運行時不攜帶類型信息。所以你必須在格式字符串中告訴printf如何解釋它們。

+0

沒有保證,但在實踐中,情況總是如此。我的做法包括架構英特爾196,英飛凌C166,飛思卡爾HCS12,瑞薩,x86,x86_64和ARM。 – SzG 2014-11-21 07:44:41