7 19下午刷題未知點集合

2021-08-21 14:14:43 字數 3728 閱讀 9591

接著上午有關 x&(x-1) 的另乙個例題:

用乙個表示式,判斷乙個數x是否是2n次方(2,4,8,16,…),不可用迴圈語句。

[中國台灣某著名cpu生產公司2023年10月面試題]

解析:2、4、8、16這樣的數轉化成二進位制是10、100、1000、10000。如果x減1後與x 做與運算,答案若是0,則x是2n次方。

答案:!(x&(x-1))

下午:1.

基本的優先順序需要記住:

指標最優,單目運算優於雙目運算。如正負號。

先算術運算,後移位運算,最後位運算。

邏輯運算最後計算。

請特別注意:1 << 3 + 2 && 7等價於 (1 << (3 + 2))&&7.

例:

型別轉換問題;算符的優先順序問題。

對於第乙個問題

unsigned char b=~a>>4,在計算這個表示式的時候,

編譯器會先把a和4的值轉換為int型別(即所謂整數提公升)後再進行計算,

當計算結果出來後,再把結果轉換成unsigned char賦值給b。

對於第二個問題

因為「~」的優先順序高於「>>」和「+」,本題的過程是這樣的:

對於1010 0101取反0101 1010;再右移

這裡有乙個問題,是先右移4位再加1呢,還是直接右移5(4+1)位。

因為「+」的優先順序高於「>>」,所以直接右移5位。結果是0000 0010。

最後的結果應該是2才對,但把如上的指令放到vs2008中執行,答案居然是250。

那麼到底是什麼地方出了問題?在除錯的過程中進入彙編指令。可以看到高階語句轉換為組合語言以後,是執行取反再位移的。

我們看到eax是16位的暫存器,於是在機器中

0xa5的寄存中表達是0000 0000 1010  0101 ,

取反是1111 1111 0101 1010,

那麼右移5位是0000 0111 1111 1010,

由於是unsigned char型的只能表示低8位的數值,即250

(x&y)+((x^y)>>1),效果就是求x與y的平均值

把x和y裡對應的每一位(指二進位制位)都分成三類,每一類分別計算平均值,最後彙總。

其中 一類是x,y中對應位 都是1, 用x&y計算其平均值;

一類是x,y中對應位 有且只有一位是1,用(x^y)>>1計算其平均值;

一類是x,y中對應位 均為0, 無須計算。

第一部分

x,y對應位均為1,相加後再除以2還是原來的數,如兩個00001111相加後除以2仍得00001111。

第二部分

對應位有且只有一位為1,用「異或」運算提取出來,然後》1(右移一位,相當於除以2)。

第三部分

對應位均為零,因為相加後再除以二還是0,所以不用計算。

三部分彙總之後就是(x&y)+((x^y)>>1)

這樣可以避免溢位:

假設x,y均為unsigned char型資料(0~255,占用一位元組),顯然,x,y的平均數也在0~255之間,但如果直接x+y可能會使結果大於255,這就產生溢位,雖然最終結果在255之內,但過程中需要額外處理溢位的那一位,在彙編中就需要考慮這種高位溢位的情況,如果(x&y)+((x^y)>>1)計算則不會。

3.利用  位運算  實現兩個整數的   加法運算

!!!!!!重點: 異或 常被認作不進製的加法運算

#include

int main(void)  

int add(int a,int b)  

注釋:*  x ^ y :實現不進製的加法,那麼我們接下來就要將進製的資料加上,就可以實現了。

*  x & y : 這個操作,即是找出相同位,為什麼我們需要找出相同的位呢,因為只 1 & 1 ,這種情況才會  產生進製,可能有人會想那 0 & 0 呢,這個沒有影響的。

*  (x & y) << 1:為什麼要左移呢,其實也很簡單,即然後我們都已經找出需要進製的位,那麼說明在該位置的前面一位,應該加上1,所以應該左移1位,就是加上餘數4.

有兩個變數a和b,不用「if」、「?:」、「switch」或其他判斷語句,找出兩個數中間比較大的。

第一種:

int max = ((a+b)+abs(a-b))/2;

abs是取絕對值。

如果a>b,那麼a-b>0,所以表示式就變成了(a+b+a-b)/2=(a+a)/2=a。

如果a第二種:

int c = a-b;

char *strs[2] = ;

c = unsigned(c)>>(sizeof(int)*8-1);//判斷符號位

注釋:sizeof(int) 位元組數

sizeof(int)*8 位數

右移sizeof(int)*8 - 1 符號位

該語句的目的是求出c的最高位的值,

當該值為1時,表示c為負數,因此判斷出a小於b。

當該值為0時,表示c為零或者整數,因此判斷出a大於等於b

5.給三個整數a、b、c,函式實現取三個數的中間數,不可以使用sort,整數操作盡可能少。

(思路:輸入的三個值 中值就是第二大的數值

選中兩個進行比較 找到較大的

較大的與第三個值比較

1.如果較大的 < 第三個值 那這個較大的 就是第二大的數值 就是中值

2.較大的 > 第三個值  比較第三個值與 較小的值

1.第三個值 > 較小的值 第三個值 是中值

2.第三個值 < 較小的值 較小的值 是中值)

注意等於號

int median( int a, int b, int c )

else

// 此時有 min<=max

if ( max <= c )

return max;

else // min <= max, c }6.

如何將a、b的值進行交換,並且不使用任何中間變數?

(單純的加減交換會有溢位的可能 盡量用異或)

void swap(int& a, int& b) //使用位運算也可以交換兩個值

7.評價一下c與c++的各自特點。如果乙個程式既需要大量運算,又要有乙個好的使用者介面,還需要與其他軟體大量交流,應該怎樣選擇合適的語言?

因為c++是物件導向的,在封裝、繼承、多型這些特性上,會有比較大的開銷,所以單從執行效率而言,c更適合一些。

但是和c++相比,c的圖形庫相對而言種模擬較少,而且比較簡單,所以在比較複雜的介面設計上,c++會更有優勢。因此到底用c還是c++並沒有並且的答案,如果目標平台的硬體效能比較弱,並且gui介面比較簡單,推薦用c,反之推薦c++。

套題8 22 下午

count 問題描述 李華終於逃離了無盡的英語作文,重獲自由的他對一棵樹產生了興趣。首先,他想知道一棵樹是否能分成大小相同的幾塊 即切掉一些邊,使得每個 連通塊的點數相同 然後,他覺得這個問題過於簡單,於是他想知道一共有多 少種方案可以把這棵樹分成大小相同的幾塊。然後他發現自己不會了,於是向聰明的你...

濟南刷題衝刺 Day1 下午

time limit 1000ms memory limit 128mb 題目描述 lyk出了道水題。這個水題是這樣的 有兩副牌,每副牌都有n張。對於第一副牌的每張牌長和寬分別是xi和yi。對於第二副牌的每張牌長和寬分別是aj和bj。第一副牌的第i張牌能覆蓋第二副牌的第j張牌當且僅當xi aj並且y...

7 19晚牛客網刷題未知點 錯題 集合

初始化為null 0 的類指標可以安全的呼叫不涉及類成員變數的類成員函式而不出錯,但是如果類成員函式中呼叫了類成員變數則會出錯 2.悄咪咪加乙個注意點 注意enum在c語言中是關鍵字 c語言對大小寫比較敏感,所以enum是乙個識別符號,但不是關鍵字。3.include usingnamespace ...