一.基本原理
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...