日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

7-19下午刷题未知点集合

發布時間:2025/3/19 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 7-19下午刷题未知点集合 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

接著上午有關 X&(X-1)?的另一個例題:

用一個表達式,判斷一個數X是否是2N次方(2,4,8,16,…),不可用循環語句。

[中國臺灣某著名CPU生產公司2007年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

?

2.

(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 <stdio.h> ?
int main(void) { ??
? ? int add(int a,int b); ?
? ? int m,a,b; ?
? ? scanf("%d,%d",&a,&b); ?
? ? m = add(a,b); ?
? ? printf("m=%d",m); ?
? ? return 0; ?
} ?
int add(int a,int b){ ?
? ? if(b == 0) return a;//沒有進位時,完成運算,a為最終和。 ?
? ? int sum,carry; ?
? ? sum = a ^ b;//沒有進位的加法運算 ?
? ? carry = (a & b) << 1;//進位,左移運算。 ?
? ? return add(sum , carry);//遞歸,相加。 ?
} ?

?

注釋:

*? 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<b,那么a-b<0,取絕對值變成-(a-b),所以表達式變成了(a+b-a+b)/2=(b+b)/2=b。

?

第二種:

int c = a-b;

char *strs[2] = {"a large","b large"};

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 )

{

int min,max;

if ( a < b )

{

min = a;

max = b;

}

else

{

min = b;

max = a;

}

// 此時有 min<=max

if ( max <= c )

return max;

else // min <= max, c <max,

{

// 比較min和c

if ( min <= c ) // min <=c < max

return c;

else

return min; // c< min <= max

}

}

?

6.

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

(單純的加減交換會有溢出的可能 盡量用異或)
void swap(int& a, int& b) //使用位運算也可以交換兩個值

{

a = a^b;

b = a^b;

a = a^b;

}

?

7.

評價一下C與C++的各自特點。如果一個程序既需要大量運算,又要有一個好的用戶界面,還需要與其他軟件大量交流,應該怎樣選擇合適的語言?

因為C++是面向對象的,在封裝、繼承、多態這些特性上,會有比較大的開銷,所以單從運行效率而言,C更適合一些。

但是和C++相比,C的圖形庫相對而言種類比較少,而且比較簡單,所以在比較復雜的界面設計上,C++會更有優勢。因此到底用C還是C++并沒有并且的答案,如果目標平臺的硬件性能比較弱,并且GUI界面比較簡單,推薦用C,反之推薦C++。

總結

以上是生活随笔為你收集整理的7-19下午刷题未知点集合的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。