深入理解計算機系統學習之信息的表示和處理

1 ,c語言的位級運算

分爲:或,與,非,異或,取反
常見用法爲掩碼運算。
x & 0xFF 生成一個由x的低位有效字節的值,其他的字節被設置爲0.
x | 0xFF 生成一個最低位爲1,其他不變。

2,c語言的移位運算

在於邏輯右移和算術右移的區別
邏輯右移:左端補0
算術右移:左端補k個最高有效位的值
對於無符號數,右移必須是邏輯的,對於有符號數,兩種都可以,一般都是算術右移。

3,無符號數編碼和有符號數的補碼

無符號數編碼:整型數據w位,範圍從{0~2^w-1}
有符號補碼:{-2^w ~ 2^w-1},將最高有效位解釋爲負權,權重爲-2^w-1.
爲什麼補碼範圍不對稱?
因爲一半的位模式(符號位設置爲1)表示負數,一半的數(符號位設置爲0)表示非負數。然而0爲非負數,意味着正數比負數少一個。
c庫中頭文件limits.h,定義了一組常量來限定不同整型數據類型的範圍:INT_MAX,INT_MIN,UINT_MAX

4,無符號數與有符號數之間的相互轉換

有符號數-》無符號數:
位值不變,只是改變了解釋這些位的方式,對於數x,w位
x = x+2^w ;x<0
x = x; x>=0
無符號數-》有符號數
數u,w位,
u= u; u < 2^(w-1)
u = u - 2^w; u>=2^(w-1)

5,爲什麼宏INT_MIN要寫成-2147483647-1?

-2147483648 被看做爲一個常量表達式,而不是一個常量。
2147483648超出了int,long int的範圍,所以變成了unsigned long int,寫成-2147483647-1可以精確的表示成爲32位有符號數的最小數。

6,注意c語言中無符號和有符號數的表達式

執行一個運算時,一個數是有符號數,一個是無符號數,c語言將進行隱式類型轉換,將有符號數轉換爲無符號數。
比如在

int sum(int a[i] ,unsigned length)
{
     sum = 0;
     int i;
     for(i = 0;i< length-1;i++)
         sum +=a[i];
     return sum;
}

當無符號數length= 0 時,0-1,將轉換爲最大的數,數組溢出,訪問到不定的內存中去。

7,size_t 的安全漏洞

原型: size_t strlen(const char * s)
編寫函數判斷一個字符串是否比另一個更長。

int strlonger(char * s,char * t)
{
    return strlen(s)-strlen(t) > 0;
}

在頭文件stdio.h中數據類型size_t 是定義爲unsigned int 的。
如果strlen(s) < strlen(t) ,會產生負數,轉換爲無符號數是,變爲一個很大的正數。
應該改爲:return strlen(s) > strlen(t)

發佈了47 篇原創文章 · 獲贊 6 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章