在C語言中,signed/unsigned用於修飾整數變量,signed表示有符號的,unsigned表示無符號的。 今天就帶大家了解一下 關鍵字signed和unsigned 。

1、signed
sign的本意是“標記,做記號”,ed后綴有一種完成時的感覺,這里表示的是有符號的。
signed關鍵字是ISO/ANSI C90標准新增的,其常見於整數類型的符號規定處 。
signed的作用是:聲明有符號類型的整數類型。
其實說signed很常見也不見得,因為我們常用的int、short和long,以及long long,默認情況下都是signed有符號的
所以相比起來unsigned的戲份可能比signed更多,signed在這里只是相當於刻意地去說明其后面的變量是有符號類型的
signed int a; /* 通常這里帶signed的變量定義都可以省略掉signed,因為signed本身就是默認的 */
signed short int b;
signed short c;
signed long int d;
signed long e;
signed long long f;
unsigned int g; /* 寫上signed后,上面的定義似乎在刻意地大聲說“上面這些變量應該是有符號的” */
unsigned short h; /* 但一般unsigned的戲份還是比signed多,signed關鍵字和auto關鍵字的宿命類似 */
有符號數在計算機中的的表示方法:在計算機內部,是用補碼表示有符號數
-正數的補碼是其本身
-負數的補碼為負數的絕對值得各個位取反加1
舉個例子:
8位整數 5的補碼為:0000 0101
8位整數 -7的補碼為:取絕對值|-7| = 7 --> 二進制為 0000 0111 --> 各個位取反 1111 1000 -->最后加1 -->1111 1001,所 以-7在計算機中就表示為1111 1001。
16位整數 20的補碼為:0000 0000 0001 0100
16位整數 -13的補碼為:1111 1111 1111 0011(可自行推導)

2.unsigned
unsigned意為“沒有標記過的”,在C語言中表示無符號的,與關鍵字signed對應
這個關鍵字在很多頭文件的變量定義中還是很常見的,一般用在整數類型的符號說明處
unsigned的作用是:聲明無符號的整數類型。
unsigned的使用和signed類似,unsigned一般加在int等整數類型名稱前:
/* unsigned可以修飾的幾種類型 */
unsigned int a; /* 無符號整型 */
unsigned short b; /* 無符號短整型 */
unsigned long c; /* 無符號長整型 */
unsigned long long d; /* 無符號long long類型 */
引入signed和unsigned的概念后,就要嚴格注意輸入輸出時候的格式了。
printf("%d, %u", a, b); /* %u是unsigned類型的說明符 */
printf("%u, %d", a, b); /* 如果對signed類型的變量用%u,那就不會去找內存中的符號位,全部當數字位處理 */
/* 這時顯示的結果可能與signed本身想表達的值差異很大,數字0情況除外 */
unsigned short c = 4;
printf("%hu"); /* %h是短整型,%hu表示無符號短整型 */
unsigned long d = 5;
printf("%lu"); /* %l是長整型,%lu表示無符號長整型 */
對於long和long long常量,能使用后綴直接給出unsigned的屬性:
120L; /* L后綴表示long常量 */
120LU; /* 再加上U后綴表示unsigned */
120LLU; /* LLU表示unsigned long long */
120ull; /* ull這樣寫也對 */
無符號數在計算機中的表示方法:計算機用原碼表示無符號數
-無符號數默認為正數n
-無符號數沒有符號位無符號數最小值為0,最大值為其所占的位數全為1時的值。
例如
8位無符號整數,最小值為0,最大值為二進制1111 1111,轉換為十進制就是255。
對於固定長度的無符號數,
MAX_VALUE + 1 = MIN_VALUE
MIN_VALUE - 1 = MAX_VALUE
C語言中變量默認 為有符號的類型,如要將變量聲明為無符號數,則需要使用unsigned關鍵字(C語言中只有整數類型能夠聲明為unsigned無符號變量)。
#include
int main()
{
int i; //默認i為有符號數
signed int j; //顯示聲明j為有符號數
unsigned char min_value = 0; //顯示聲明k為無符號數
unsigned char max_value = 255;
unsigned char sub_result = min_value - 1; //無符號數最小值 - 1 = 最大值
unsigned char add_result = max_value + 1; //無符號數最大值 + 1 = 最小值
printf( "%d\n", sub_result ); //分析輸出 255
printf( "%d\n", add_result ); //分析輸出 0
return 0;
}
輸出結果 :
255
0

3、signed和unsigned的區別
總結:signed和unsigned用於修飾整數類型(包括char,從ANSI C89標准開始支持)。
signed是默認的 ,表示這個變量是有符號的, 也就是可以存儲整數和負數
unsigned則需要顯示給出,表示這個變量沒有符號值能存儲數的大小,而不能表示正負
signed存儲符號是有代價的,代價就是存儲空間中的一個比特位,專門用來存儲符號,這一位不能表示數值
所以 ,一般來說 ,同類型的signed能夠存儲的數的絕對值大小要小於unsigned
默認的int、short、long、long long為有符號數;換言之,int等價於signed int,short等價於signed short,long等價於signed long,long long等價於signed long long。
但是char本身是signed char還是unsigned char,取決於語言的實現(編譯器)。
數據類型范圍列表如下:

總之,signed和unsigned的區別基本就在於,是否把存儲的某一位看做符號位,unsigned時不看符號位,所以unsigned一般表示的是非負數
注意:
整數類型占多少字節空間是不確定的,只能保證sizeof(short) <= sizeof(int) <= sizeof(long)。
在32位的設備平台上,short為16位(2字節), int為32位(4字節),long為32位(4字節),long long為64位(8字節)。
在64位的設備平台上,short為16位(2字節), int為32位(4字節),long為64位(8字節),long long為64位(8字節)。
4、為什么一定要區分signed和unsigned?
看兩種情況:signed和unsigned分別存儲正數和負數,默認最高位為符號位
(1)正數6,分別用signed和unsigned方式在一個字節中存儲:0000 0110 [signed] 0000 0110 [unsigned]
(2)int類型的負數-5和正數4294967291在4個字節中的存儲:FFFF FFFB [十六進制]
上述例子有一個特點,就是不同變量在內存中的存儲形式是一樣的
由於0表示正,所以signed和unsigned的正數在內存中的表示是一樣的
而同樣的一個存儲,在signed和unsigned下就可能表示兩個不同的數(0除外)
所以unsigned類型的數一般要在輸入和輸出的時候刻意去注意。
文章參考來源:
https://blog.csdn.net/wen381951203/article/details/79922220
https://blog.csdn.net/Johan_Joe_King/article/details/84201039

如果你想更好的提升你的編程能力,學好C語言C++編程!彎道超車,快人一步!
【C語言C++學習企鵝圈子】,分享(源碼、項目實戰視頻、項目筆記,基礎入門教程)
歡迎轉行和學習編程的伙伴,利用更多的資料學習成長比自己琢磨更快哦!
編程學習書籍:

編程學習視頻:
