1. 程式人生 > >C++ 帶符號和無符號char型別賦值超出表示範圍的情況

C++ 帶符號和無符號char型別賦值超出表示範圍的情況

在C++中字元型被分為了三種:char、signed char和unsigned char。需要的注意:

  • 字元的表現形式只有兩種:帶符號的和無符號的,型別char具體使用哪一種由編譯器決定;
  • 如果需要使用不大的整數,應該明確指出它的型別是signed char或者unsigned char。

關於帶符號型別:

  • 帶符號型別在表示範圍內正值和負值的量應該平衡,例如,8位元理論上應該可以表示-127至127,大多數現代計算機將實際的表示範圍定位-128至127;
  • 當我們賦給帶符號型別一個超出它表示範圍的值時,結果是未定義的(undefined),程式可能繼續工作、可能崩潰,也可能生成垃圾資料。

關於無符號型別:

  • 無符號型別中所有位元都用來儲存值,例如,8位元的unsigned char可以表示0至255區間內的值;
  • 當我們賦給無符號型別一個超出它表示範圍的值時,結果是初始值對無符號型別表示數值總數取模後的餘數(即取模後所得的數,並不是取餘)。

例如:8位元大小的unsigned char可以表示0至255區間內的值,如果我們賦了一個區間以外的值,則實際的結果是該值對256(總數)取模後所得的餘數。
因此,把-1賦給8位元大小的unsigned char所得的結果是255,使用2種方法計算:

有整數a和b,a對b進行取模或取餘運算
1、求整數商:c=a/b
取模運算在計算商值向負無窮方向捨棄小數位
取餘運算在計算商值向0方向捨棄小數位


2、計算模或者餘數:r=a-(c*b)
注:取模運算遵循儘可能讓商小,取餘運算遵循儘可能讓餘數的絕對值小。因此,取模和取餘的結果不同。

mod為取模,rem為取餘,取模和取餘所得的結果在a和b(同為整數)符號相同 的時候是相等的

當a和b符號一致時,求模運算和求餘運算所得的c的值一致,因此結果一致。但是當符號不一致的時候,結果不一樣。

具體來說,求模運算結果的符號和b一致,求餘運算結果的符號和a一致


在本例中,將-1和256帶入a和b,c=-1/256,向負無窮方向捨棄小數得-1,計算得r=255.

計算機中帶符號的整數採用二進位制的補碼進行儲存
正數的補碼等於其二進位制編碼
負數的補碼等於其絕對值的二進位制編碼,取反,再加1
在本例中,-1的絕對值是1,二進位制編碼為0000 0001,取反加1就是1111 1111
unsigned是無符號數,會把1111 1111看成正數,剛好是255的二進位制編碼。