C語言中的正負數以及數值溢位

2021-07-24 18:20:02 字數 2834 閱讀 3886

在數學中,數字有正負之分。在c語言中也是一樣,short、int、long 都可以帶上符號,例如:

複製

格式化複製

short a =-10

;//負數

int b =+10

;//正數

long c =(-9

)+(+12

);//負數和正數相加

short a = -10;  //負數

int b = +10; //正數

long c = (-9) + (+12); //負數和正數相加

如果不帶正負號,預設就是正數。

符號也要在記憶體中體現出來。符號只有正負兩種情況,用1位就足以表示,這1位就是最高位。以 int 為例,它占用32位的記憶體,0~30位表示數值,31 位表示正負號。如下圖所示:

在程式語言中,計數往往是從0開始,例如字串 "abc123",我們稱第 0 個字元是 a,第 1 個字元是 b,第 5 個字元是 3。這和我們平時從 1 開始計數的習慣不一樣,大家要慢慢適應,培養程式設計思維。
在符號位中,用0表示正數,用1表示負數。例如 int 型別的 -10、+16 在記憶體中的表示如下:

如果不希望設定符號位,可以在資料型別前面加 unsigned,如下所示:

複製

格式化複製

unsigned

short a =12;

unsigned

int b =

1002

;unsigned

long c =

9892320

;

unsigned short a = 12;

unsigned int b = 1002;

unsigned long c = 9892320;

這樣,short、int、long 中就沒有符號位了,所有的位都用來表示數值。也就意味著,使用了 unsigned 只能表示正數,不能表示負數了。

如果是unsigned int,那麼可以省略 int ,只寫 unsigned,例如:

unsigned n = 100;
它等價於:
unsigned int n = 100;
輸出無符號數使用%u,**如下:

複製

格式化複製

#include

#include

intmain

()

#include #include int main()

輸出結果:

a1=1234, a1(u)=1234

a2=-1234, a2(u)=4294966062

b1=5678, b1(u)=5678

b2=-5678, b2(u)=4294961618

可以發現,無論變數宣告為有符號數還是無符號數,只有當以 %u 格式輸出時,才會作為無符號數處理;如果宣告為 unsigned 卻以 d% 輸出,那麼也是有符號數。

a2、b2 的輸出值之所以很奇怪,與它們在記憶體中的儲存形式有關,我們將在《

c語言整數在記憶體中是如何儲存的》一節詳細介紹。

最後需要說明的是:不管是否有符號,%o、%x、%x、%#o、%#x、%#x 都是以無符號形式輸出,讀者可以親自測試。short、int、long 占用的位元組數不同,所能表示的數值範圍也不同。以32位平台為例,下面是它們的取值範圍:

資料型別

所佔位元組數

取值範圍

short

2-32768~32767,即 -215

~(215

-1)unsigned short

20~65535,即 0~(216

-1)int

4-2147483648~2147483647,即 -231

~(231

-1)unsigned int

40~4294967295,即0~(232

-1)long

4-2147483648~2147483647,即 -231

~(231

-1)unsigned long

40~4294967295,即0~(232

-1)

當數值過大或過小時,有限的幾個位元組就不能表示,就會發生溢位。發生溢位時,最高位會被截去。請看下面的例子:

複製

格式化複製

#include

intmain

()

#include int main()

執行結果:

a=0, b=-1

變數 a 為 int 型別,占用4個位元組(32位),能表示的最大值為 0xffffffff,而 0x100000000 = 0xffffffff + 1,占用33位,已超出 a 所能表示的最大值,會發生溢位,最高位被截去,剩下的32位都是0。也就是說,在 a 被輸出前,其值已經變成了 0。

對於變數 b,每一位的值都是 1,包括符號位,以 %d 輸出時,按照推理應該是 -0x7fffffff = -2147483647,但是輸出結果卻是 -1,這是為什麼呢?我們將在《c語言整數在記憶體中是如何儲存的》一節解開謎底。

C語言學習筆記 6 C語言中的正負數及輸出

眾所周知,在數字表達中,數字是可以加上正負號用於分割槽正負數的。在c語言中也是如此,但是鑑於數字在計算機中的儲存方式,就需要乙個bit位來儲存符號位,如 正數 short a1 10 short a2 0x2dc9 十六進製制字首0x 負數 int b1 10 int b2 0174 八進位制字首0...

關於正負數的二進位製新發現以及求法

在做藍橋杯真題的時候發現了一種求二進位制的很厲害的求法,先看 i表示二進位制數。1 void tobinarystr int i,string ans 212 13 14 else 1523 24 2526 對於正數的二進位制,高位一定是0 string從左往右依次表示高位到低位 因為正的二進位制數...

C語言中的整數溢位

對於初學者來說,c語言的整數溢位可能一開始可能會不好理解。對於乙個位元組的 unsignde char型別和signed char 型別。賦值乙個超出其儲存範圍的數值時,其真實儲存的數值並不等於我們賦值的資料。要弄清整數溢位問題,首先必須清晰計算機中數值都是以補碼形式儲存的,要會原碼 反碼和補碼的轉...