2.42 編寫一個c表達式,生成一個字,由x的最低有效字節和y中剩下的字節組成。對於對於運算數 x = 0x89ABCDEF 和 y = 0x76543210,生成的結果是0x765432EF函數
答:分析一下,測試
a>. 這道題目主要考的是我們邏輯運算的使用,首先我們來回顧一下都有哪些邏輯運算:spa
按位與(&):(雙目運算)相同位均爲1,結果爲1,不然結果爲0code
按位或(|):(雙目運算)相同位有一個是1的結果爲1,不然結果爲0blog
按位異或(^):(雙目運算)相同位值相同的結果爲0,不然爲1it
按位取反(~):這是單目運算,有效位值是1的,結果爲0,值爲0的結果爲1io
還有其餘的幾個運算:什麼同一運算、位移運算(左移位運算<<;右移位運算>> 又分爲正數和負數,正數跟左移位運算同樣,負數就分爲邏輯運算補0,算術運算補1的區別)class
b>. 從結果來看0x765432EF的前三位是y的前三位0x76543200,最後一位是x的最後一位0x000000EF,可否經過邏輯運算來分別獲得呢?二進制
0x76543200:y1 = y & 0xffffff00 == 0x76543210 & 0xffffff00 = 0x76543200程序
0x000000EF:x1 = x & 0x000000ff == 0x89ABCDEF & 0x000000ff = 0x000000EF
最後兩個結果(y1 + x1 或者使用按位或運算 x1 | y1兩種方式都行)代碼以下:
#include <stdio.h> int main(void) { int x, y; int x1, y1, r1; printf("Please is a x and y: "); scanf("%x %x", &x, &y); printf("x = %.8x and y = %.8x\n", x, y); x1 = x & 0x000000ff; y1 = y & 0xffffff00; //r1 = x1 + y1;//這種是相加的方法 r1 = x1 | y1;//這種仍是使用了邏輯運算按位或運算,相同位值有1的結果爲1,否則結果爲0 printf("x1 = %.8x and y1 = %.8x and r1 = %.8x\n", x1, y1, r1); return 0; }
2.43 只用位級和邏輯運算,編寫出c表達式,在下列描述狀況下產生1,而其餘狀況下獲得0,你的代碼應該能在因此字長的機器上運行,加上x是正數:
A. X的任何位都等於1 B. x的任何位都等於0 C. x的最低有效字節中的位都等於1 D. X的最低有效位的字節都等於0
答:位級和邏輯運算在上一題中已經回顧,分析如下四種狀況:
A. X的任何位都等於1:這個可使用 按位或(|)運算來實現,好比x = 0x00000001 ===> x | 0xffffffff = 0xffffffff,或者使用取反再按位異或 ~x ^ x或者取反再按位或~x | x
B. X的任何位都等於0:使用按位異或,相同位0,反之爲1,x ^ x
C. X的最低有效位字節位都爲1:使用按位或運算或者算術右移運算
D. X的最低有效位字節位都爲0:左移運算或者按位與運算
2.44 編寫一個函數is_shifts_are_arithmetic(),使得這個函數在對整數使用算術右移的機器上運行時生成1,而其餘狀況下生成0,你的代碼用該能夠運行在任何字長的機器上。在幾種機器上測試你的代碼,編寫並測試過程unsigned_shifts_are_arithmetic(),該過程肯定對無符號整數使用的位移形式。
答:分析一下:這道題主要考我們位移運算:左位移、右位移(正數與左位移同樣,負數分爲邏輯運算補0、算術運算補1)
第一種狀況:算術右移的機器上邊,經過算術右移獲得結果1,設想一下算術右移,左邊補齊有效位的是1,那麼這時候該怎麼辦呢?1 = 0 + 1這個表達式熟悉嗎?對,就是二進制補碼,設想一下,神馬狀況下經過右移,能獲得0呢?算術右移補的是1,那麼假設我們先右移sizeof(int)位,獲得的結果必然是全部的有效位都爲1,怎麼轉換成0呢????有人想到取反,那你最後怎麼加上1呢??那就是給右移後的數添加負號,仔細想一下,當全部有效位都是1的時候,添加一下負號,那結果會是什麼???我們來計算一下它x的補碼(補碼 = ~x +1),那麼結果就是咱們想要的
第二種狀況:邏輯右移的機器上邊,經過邏輯右移獲得結果0,設想一下,什麼狀況下右移的結果會是0,很明顯是當你右移到全部有效位都是0的時候,結果就爲0了
基於上邊的分析,什麼狀況下右移到整數結果所有爲0呢??只有當右移sizeof(int)位,才能獲得全爲0(右移,邏輯運算,左邊補0,右移幾位截取掉幾位,直到全部有效位都爲0爲止),因爲程序須要通用,全部獲得全部有效位全爲0的數x,添加負號變成-x,我們來計算它的補碼,-x = ~x + 1 = 0(好比是4位 -x = -0000 = 1111 + 1 = 10000,保留4位有效數字,最高位截取掉後,剩餘有效位是0000)
2.45