【C語言深度剖析】讀書筆記之 signed ,unsigned
1.4,signed、unsigned 關鍵字
我們知道計算機底層只認識0、1.任何資料到了底層都會變計算轉換成0、1.那負數怎麼儲存呢?肯定這個“-”號是無法存入記憶體的,怎麼辦?很好辦,做個標記。把基本資料類
型的最高位騰出來,用來存符號,同時約定如下:最高位如果是1,表明這個數是負數,其值為除最高位以外的剩餘位的值添上這個“-”號;如果最高位是0,表明這個數是正數,
其值為除最高位以外的剩餘位的值。這樣的話,一個32位的signed int型別整數其值表示法範圍為:- 2^31~2^31 -1;8 位的char型別數其值表示的範圍為- 2^7~2^7 -1。一個32位的unsigned int型別整數其值表示法範圍為:0~ 2^32 -1;8位的char型別數其值表示的範圍為0~2^8 -1。同樣我們的signed 關鍵字也很寬恆大量,你也可以完全當它不存在,編譯器預設預設情況下資料為signed 型別的。
上面的解釋很容易理解,下面就考慮一下這個問題:
int main()
{
char a[1000];
int i;
for(i=0; i<1000; i++)
{
a[i] = -1-i;
}
printf("%d",strlen(a));
return 0;
下面的補碼錶示數:
11111111 -1
11111110 -2
11111101 -3
11111100 -4
…… ……
10000001 -127
10000000 -128
01111111 -129
…… ……
00000000 -256
此題看上去真的很簡單,但是卻鮮有人答對。答案是255。別驚訝,我們先分析分析。
for 迴圈內,當i 的值為0 時,a[0]的值為-1。關鍵就是-1 在記憶體裡面如何儲存。
我們知道在計算機系統中,數值一律用補碼來表示(儲存)。主要原因是使用補碼,可
以將符號位和其它位統一處理;同時,減法也可按加法來處理。另外,兩個用補碼錶示的數
相加時,如果最高位(符號位)有進位,則進位被捨棄。正數的補碼與其原碼一致;負數的
補碼:符號位為1,其餘位為該數絕對值的原碼按位取反,然後整個數加1。
按照負數補碼的規則,可以知道-1 的補碼為0xff,-2 的補碼為0xfe……當i 的值為127
時,a[127]的值為-128,而-128 是char 型別資料能表示的最小的負數。當i 繼續增加,a[128]
的值肯定不能是-129。因為這時候發生了溢位,-129 需要9 位才能儲存下來,而char 型別
資料只有8 位,所以最高位被丟棄。剩下的8 位是原來9 位補碼的低8 位的值,即0x7f。
當i 繼續增加到255 的時候,-256 的補碼的低8 位為0。然後當i 增加到256 時,-257 的補
碼的低8 位全為1,即低八位的補碼為0xff,如此又開始一輪新的迴圈……
按照上面的分析,a[0]到a[254]裡面的值都不為0,而a[255]的值為0。strlen 函式是計
算字串長度的,並不包含字串最後的‘\0’。而判斷一個字串是否結束的標誌就是看
是否遇到‘\0’。如果遇到‘\0’,則認為本字串結束。
分析到這裡,strlen(a)的值為255 應該完全能理解了。這個問題的關鍵就是要明白char
型別預設情況下是有符號的,其表示的值的範圍為[-128,127],超出這個範圍的值會產生溢
出。另外還要清楚的就是負數的補碼怎麼表示。弄明白了這兩點,這個問題其實就很簡單了。
相關文章
- 【記】《.net之美》之讀書筆記(一) C#語言基礎筆記C#
- C語言程式設計讀書筆記:結構C語言程式設計筆記
- 《深度探索C++物件模型》讀書筆記C++物件模型筆記
- 《深度探索c++記憶體模型》讀書筆記 (二)C++記憶體模型筆記
- c語言筆記C語言筆記
- 《論語》讀書筆記筆記
- C程式設計語言讀書筆記:型別運算子與表示式C程式程式設計筆記型別
- C語言學習筆記之變數C語言筆記變數
- 《Go 語言程式設計》讀書筆記(十)反射Go程式設計筆記反射
- 《Go 語言程式設計》 讀書筆記 (八) 包Go程式設計筆記
- 《Go 語言程式設計》讀書筆記(四)介面Go程式設計筆記
- 《Go 語言程式設計》讀書筆記 (三) 方法Go程式設計筆記
- 《Go 語言程式設計》讀書筆記 (二)函式Go程式設計筆記函式
- 讀書筆記:組合語言(王爽)實驗七筆記組合語言
- swift語法-讀書筆記Swift筆記
- 《Effective C++》讀書筆記C++筆記
- C++讀書筆記:字串C++筆記字串
- C 語言學習筆記筆記
- C語言學習筆記C語言筆記
- C語言指標筆記C語言指標筆記
- 《Go 語言程式設計》讀書筆記 (九) 命令工具集Go程式設計筆記
- 【記】《.net之美》之讀書筆記(二) C#中的泛型筆記C#泛型
- JVM讀書筆記之OOMJVM筆記OOM
- 《C缺陷與陷阱》讀書筆記筆記
- 《Go 語言程式設計》讀書筆記 (五) 協程與通道Go程式設計筆記
- C語言學習筆記--C運算子C語言筆記
- C語言學習筆記之指標的運算C語言筆記指標
- 《Maven實戰》之讀書筆記Maven筆記
- c語言-記錄閱讀《c缺陷與陷阱》C語言
- 《Java8函數語言程式設計》讀書筆記---類庫Java函數程式設計筆記
- 《Go 語言程式設計》讀書筆記(十一)底層程式設計Go程式設計筆記
- c語言學習筆記===函式C語言筆記函式
- C語言筆記——自定義型別C語言筆記型別
- JVM讀書筆記之記憶體管理JVM筆記記憶體
- 讀書筆記筆記
- 《數學之美》讀書筆記&思考筆記
- 《讀書與做人》讀書筆記筆記
- 《Java8函數語言程式設計》讀書筆記---收集器Java函數程式設計筆記
- 初識C語言(01)—學習筆記C語言筆記