誰能幫我理解有符號/無符號整數和有符號/無符號字符之間的區別?在這種情況下,如果它是無符號的,那么該值不會永遠達到負數并繼續無限回圈 0 嗎?
int main()
{
unsigned int n=3;
while (n>=0)
{
printf ("%d",n);
n=n-1;
}
return 0;
}
uj5u.com熱心網友回復:
兩個重要的事情:
在一個層面上,常規signed與unsigned值之間的區別只是我們解釋位的方式。如果我們將自己限制為 3 位,我們有:
| 位 | 簽 | 未簽名 |
|---|---|---|
| 000 | 0 | 0 |
| 001 | 1 | 1 |
| 010 | 2 | 2 |
| 011 | 3 | 3 |
| 100 | -4 | 4 |
| 101 | -3 | 5 |
| 110 | -2 | 6 |
| 111 | -1 | 7 |
位模式不會改變,只是解釋問題是我們讓它們表示從 0 到 2 N -1 的非負整數,還是從 -2 N/2到 2 N/2 -1 的有符號整數。
另一個需要了解的重要事情是在型別上定義了哪些操作。對于無符號型別,加法和減法被定義為“環繞”從 0 到 2 N -1。但是對于有符號型別,上溢和下溢是未定義的。(在某些機器上,它們會環繞,但不是全部。)
最后,還有正確匹配printf格式的問題。對于%d,你應該給它一個有符號整數。但是你給了它unsigned。嚴格來說,這也會導致未定義的行為,但在這種情況下(并不太令人驚訝),發生的事情是它采用了相同的位模式并將其列印出來,就好像它是有符號的,而不是無符號的。
uj5u.com熱心網友回復:
值不會永遠達到負數嗎
沒錯,不能是負數。
并繼續 0 的無限回圈
不,它會從零環繞到 an 的最大值unsigned int,這是明確定義的行為。如果您使用正確的轉換說明符%u而不是不正確的%d,您會注意到以下輸出:
3
2
1
0
4294967295
4294967294
...
uj5u.com熱心網友回復:
有符號數表示是正整數和負整數的分類,而無符號分類是正整數的分類,您撰寫的代碼將永遠運行,因為 n 是無符號數并且始終表示正數。
uj5u.com熱心網友回復:
在這種情況下,如果它是無符號的,那么該值是不是永遠不會達到負數......?
你是對的。但是在printf ("%d",n);你“欺騙”了printf()函式的陳述句中——使用
您可以不斷地增加/減少一個數字。
uj5u.com熱心網友回復:
有符號整數可以包含正值或負值。
C 和 C 中的 int 型別(有符號和無符號)通常有 16 位。這意味著它們都能夠保存 2^16 (65,536) 個唯一數字。
有符號 int 型別的可能值范圍從 -32,768 (-2^15) 到 32,767 (2^15-1)。如果您計算從 -32,768 到 32,767 的整數數量,將有 65,536 個。
另一方面,unsigned int 型別的最小值為 0,最大值為 65,535 (2^16 - 1)。
char 型別,有符號和無符號,代表單個位元組(八位)。它可以容納 256 個值。對于有符號 char 型別,取值范圍為 -128 到 127。對于無符號 char 型別,取值范圍為 0 到 255。
現在,關于您發布的代碼。是的,它將永遠運行。不,它不會無限列印零。當您有一個值為 0 的 unsigned int(或任何其他存盤整數值的型別)并減去 1 時,您最終會得到該型別的最大值。
這同樣適用于 signed int 。如果您有一個有符號 int 存盤它可以保存的最低可能值,然后減去一,它將成為最高值。
uj5u.com熱心網友回復:
術語有符號和無符號是指 CPU 如何處理位序列。
這里有兩件重要的事情需要理解:
- CPU 如何將有限位序列添加到單個有限結果中
- CPU 如何區分有符號和無符號運算元
讓我們從(1)開始。
讓我們以 4 位半位元組為例。
如果我們要求 CPU 加上0001和0001,結果應該是 2,或者0010。但是如果我們要求它加上1111and 0001,結果應該是 16, or 10000。但它只有 4 位來包含結果。約定是將環繞或圈成 0,有效地忽略最高位。另請參見整數溢位。.
為什么這是相關的?因為它產生了一個有趣的結果。也就是說,根據上面的定義,如果我們讓x = 1111,那么我們得到x 1 = 0。嗯,x, 或者1111,現在看起來和行為都非常像-1。這就是有符號數和運算的誕生。如果1111可以看作是-1,那么1111 - 1 = 1110應該是-2,以此類推。
現在讓我們看看(2)。
當 C 編譯器看到您定義了一個 時unsigned int,它將使用特殊的 CPU 指令來處理它認為相關的無符號數。例如,這與jump指令相關,CPU 需要知道您的意思是向前跳躍還是略微向后跳躍。為此,它需要知道您的運算元是要以有符號還是無符號方式進行解釋。
另一方面,將兩個數字相加的操作從根本上忽略了隨后的解釋。唯一的事情是,CPU 會在加法操作后打開一個特殊標志,告訴您是否發生了回繞,供您自己審核。
但要理解的重要一點是位序列不會改變;只有它的解釋。
要將所有這些與您的示例聯系起來,從無1符號中減去0將簡單地環繞回1111, 或在您的情況下為 2^32 。
最后,有符號/無符號還有其他用途。例如,由于它被定義為不同的型別,這允許撰寫定義合同的函式,假設只有無符號整數可以傳遞給它。此外,當您想要顯示或列印數字時,它也很重要。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/367268.html
