char 和 unsigned char 的區別

2021-10-03 10:55:28 字數 2853 閱讀 8544

一.基本原理

1、char取值範圍是 -128~+127。

2、我們先來看 signed char的最大值。  

最高位是 符號位, 0 代表正數; 1 代表負數。0 1 1 1  1 1 1 1     這個值等於 2^0 + 2^1 + 2^2  + 2^3  + 2^4  + 2^5  + 2^6  = 127  。 也有乙個簡便計算方法:2^7 -1 = 128-1 =127   所以,signed char 的最大值是 127 。

singed char 的最小值計算。 在計算機中,數值是以補碼形式儲存的。正數的補碼是其本身; 而負數的補碼是 取反 (符號位保持不變),再加1。

我們先來看 -1 的儲存過程:

-1: 1 0 0 0 0 0 0 1 ->(取反) 1 1 1 1 1 1 1 0 ->(加1) 1 1 1 1 1 1 1 1

-2: 1 0 0 0 0 0 1 0 ->(取反) 1 1 1 1 1 1 0 1 ->(加1) 1 1 1 1 1 1 1 0

-3: 1 0 0 0 0 0 1 1 ->(取反) 1 1 1 1 1 1 0 0 ->(加1) 1 1 1 1 1 1 0 1

-127 1 1 1 1 1 1 1 1 ->(取反) 1 0 0 0 0 0 0 0 ->(加1) 1 0 0 0 0 0 0 1

-128 1 0 0 0 0 0 0 0 ->(取反) 1 1 1 1 1 1 1 1 ->(加1) 1 0 0 0 0 0 0 0

不管是原碼還是補碼, 總會出現 -0 這個值。 本來 +0 與 -0 是沒有區別的。 但對於儲存器和編譯器來講,總得充分利用每個位元組吧, 更不想出現二義性。 所以,將 -0 表示為 -128 , 這樣既增大了signed char 數值的表示範圍,又消除了 -0 的二義性。

所以signed char的取值範圍是 -128~127。

3.unsigned char沒有符號位  最大值是  255(1 1 1 1 1 1 1 1)

我們看下下面的**測試程式,就會清晰很多了

#includeusing namespace std;

int main(int argc, char * ar**)

printf("a is %d\n", a);

//對其賦值給 unsigned char的時候,是會直接把a中在記憶體中儲存的值

//10000001,而賦值給 unsigned char之後,unsigned char之後會當

//原始碼進行解析,則又恢復了原來的129.

unsigned char w = a;

printf("w is %d\n", w);

/* -1 在計算機中按照補碼儲存 儲存的數值是 11111111

把這個值賦值給乙個 unsigned char 之後就會按照原始碼處理

沒有符號位翻譯成了 255

*/ char testc = -1;

unsigned char test_uc = testc;

printf("test_uc =%d\n", test_uc);

return 0;

}

輸出內容如下:

a is -127

w is 129

test_uc =255

二.printf 輸出的影響

在c中,預設的基礎資料型別均為signed,如定義變數為int,long等,都為有符號的。如果要定義無符號型別,必須顯式地在變數型別前加unsigned。

char vs unsigned char

相同點:在記憶體中都是乙個位元組,8位(2^8=256),都能表示256個數字

不同點:char的最高位為符號位,因此char能表示的資料範圍是-128~127,unsigned char沒有符號位,因此能表示的資料範圍是0~255

實際使用中,如普通的賦值,讀寫檔案和網路位元組流都沒有區別,不管最高位是什麼,最終的讀取結果都一樣,在螢幕上面的顯示可能不一樣。

但是要把乙個char型別的變數賦值給int、long等資料型別或進行類似的強制型別轉換時時,系統會進行型別擴充套件,這時區別就大了。對於char型別的變數,系統會認為最高位為符號位,然後對最高位進行擴充套件,即符號擴充套件。若最高位為1,則擴充套件到int時高位都以1填充。對於unsigned char型別的變數,系統會直接進行無符號擴充套件,即0擴充套件。擴充套件的高位都以0填充。所以在進行類似的操作時,如果char和unsigned char最高位都是0,則結果是一樣的,若char最高位為1,則結果會大相徑庭。

#include /*

%d,%c,%s,%x是程式組合語言中的格式符,它們的含義:

1、%d表示按整型資料的實際長度輸出資料。//不會進行擴充套件到四個位元組

2、%c用來輸出乙個字元。就輸出乙個位元組裡的內容,然後得到數值,不關心符號位,直接把對應的二進位制變成乙個正數

//找對應的acs碼符號

3、%x表示以十六進製制數形式輸出整數。

//會擴充套件到四個位元組 char型別的負數賦值給他影響較大,

所有高位都會擴充套件為1,其他位都不變(包括原來的符號位)

這個一般的辦法是把高位清零來看,就是與0xff想與

4、%u表示以無符號十進位制整數形式輸出整數。

//會擴充套件到四個四節

char型別的負數賦值給他影響較大,

所有高位都會擴充套件為1,其他位都不變(包括原來的符號位)

*/static void func(unsigned char uc)

int main(int argc, char *ar**)

輸出結果如下:

暫時總結到這裡

char 和char 的區別

1 char是乙個陣列定義,char 是指標定義 也稱char為靜態陣列,char 為動態陣列 2 指標和陣列的區別 1 指標和陣列的分配 陣列是開闢一塊連續的記憶體空間,陣列本身的識別符號 也就是通常所說的陣列名 代表整個陣列,可以使用sizeof來獲得陣列所佔據記憶體空間的大小 注意,不是陣列元...

char 和char 的區別

char c abc c 0 t char c1 def c1 0 t err 首先c1是乙個指標,它只是指向 def 這個記憶體塊。而 abc 是乙個常量區,不可以對其進行更改。而c定義的是乙個陣列,在分配記憶體時,會自動給它分配四個位元組的位址,並且會進行乙份拷貝工作,此時分配是在棧區進行的,是...

char 和char 的區別

之前在用到char 和char,用到srtncat,讓char對char 進行新增時執行會崩潰,之後做了一些分析和練習,對char 和char有了更深的理解。下面附上一些測試資料。include include include using namespace std int main cout do...