第二部分
?? 信息的表示和處理
?
信息存儲:
?? 二進制(0101001), 八進制,十六進制(0x32FD)
? 字(word size)指明整數和指針數據的標稱大小(normal size),對于w位的機器而言,虛擬地址范圍0-2w-1,
如32位機器最大尋址為4GB,無符號整數表示0-42億
? 數據大小 根據數據類型(int float bool等)
? 尋址和字節順序 大端小端的問題(兩種表示方法,在網絡通訊的時候可能會產生問題,需要注意)
大端:最高有效位字節在前面
小端:最低有效位字節在前面
下圖所示為小端表示機器顯示結果(-12345的補碼表示 0xCFC7)
?
?
布爾代數和布爾環
當考慮長度為w的位向量上的^,&和~運算時,會得到一種不同的數學形式,我們稱之為布爾環( Boolean ring)
布爾環與整數運算有很多相同的屬性。 如 整數運算的一個屬性是每個值x都有一個加法逆元(additive inverse)-x
使得x+(-x) = 0。? 布爾環的的“加法”是^(異或),即 a^a = 0;
因此 (a^b)^a= b? 固有一下的代碼:
void inplace_swap(int* x, int* y){*y = *x ^ *y; // x =x , y = x ^ y *x = *x ^ *y; //x = x ^(x^y) = y, y = x ^ y*y = *x ^ *y; //y = y ^ (x ^ y) = x , }
?
以下代碼可能會出現的問題:數組個數為奇數時,中間一位的數字變為0,奇數時正常逆序
void reverse_array(int a[],int cnt){int first, last;for(first = 0,last = cnt - 1; first <= last; first++,last--)inplace_swap(&a[first],&a[last]); }
原因: 因為奇數時中間一位 調用inplace_swap()函數,a^a = 0;
修改方法: 1、在inplace_swap()前加上 if( first != last)判斷, (ps: 后來看答案是 first< last,這種改法更合理)
??????????????? 2、修改inplace_swap()函數
?
C語言中的移位運算:
邏輯右移:在左端補k個0
算術右移:在左端補k個最高有效位的值(最有符號數據的運算非常有用)
? 小結:? 無符號數邏輯右移和算術右移的位表示是一樣的,
???????????? 有符號數則不一樣(有符號數采用補碼表示),幾乎所有的編譯器/機器組合都對有符號數采用算術右移,程序員都??? 假設是機器會使用算術右移。
ps: 左移 =* 2n? 右移? =/2n
????? 移位運算優先級較低,低于加減? 如果不清楚就增加括號,? 如 1 << 2 + 3 <<? 4 實際意義: 1 << 5 << 4
?
?
有符號數與無符號數之間的轉換:
?????? Ps: 一般機器有符號數都用補碼表示(但不是標準和原則)
要點:
?? 1、C語言運行無符號數和有符號數轉換,轉換的原則是位表示保持不變
?? 2、將無符號數擴展成更大的數據類型,在表示的開頭加0,稱為零擴展
?? 3、將一個數的補碼轉換為一個更大的數據類型可以執行符號擴展,添加最高有效位的值的副本
//數據轉換 擴展short sx = -12345;unsigned short usx = sx; //53191int x = sx;unsigned int ux = usx;printf("sx = %d\t",sx);show_bytes((byte_pointer)&sx,sizeof(short));printf("usx = %u\t",usx);show_bytes((byte_pointer)&usx,sizeof(unsigned short));printf("x = %d\t",x);show_bytes((byte_pointer)&x,sizeof(int));printf("ux = %u\t",ux);show_bytes((byte_pointer)&ux,sizeof(unsigned));
結果如下: