C語言博大精深

2021-10-08 06:26:41 字數 3528 閱讀 2438

​ 因為計算機的運算模式是以二進位制為基礎,所以十進位制運算在計算時會被轉換成二進位制再進行運算,而轉換過程就會導致執行速度降

低。所以運用位運算可以提高**執行的效率。

​ 位運算說穿了,就是直接對整數在記憶體中的二進位制位進行操作。

​ 注意,位運算只針對於整數進行操作。

二、位運算的使用規則

​ 位運算的使用方法可以網上搜尋,各種各樣的不同角度解釋都有。這裡只進行簡單的規則介紹。附上菜鳥教程鏈結。

符號描述規則&

與全1為1,有0則0|或

有1則1,全0為0^異或

「同」為0,」不同「為1~取反

1變0, 0變1

>>

右移二進位制位全部右移若干位,正數左補0,負數左補1,右邊丟棄。

<<

左移二進位制位全部左移若干位(左邊的二進位制位丟棄,右邊補0)。

​ 下面是具體規則的使用。

/*與*/0&

0=0;

0&1=

0;1&

0=0;

1&1=

1;/*或*/0|

0=0;

0|1=

1;1|

0=1;

1|1=

1;/*異或*/0^

0=0;

0^1=

1;1^

0=1;

1^1=

0;/*取反*/~1

=0;~

0=1;

/*左移*/a(

60)=0011

1100

a<<

20011

1100

=>

1111

0000

↑ ↑

高位 低位

溢位 不夠

捨棄 補0

/*右移*/a(

60)=0011

1100

a>>

20011

1100

=>

0000

1111

↑ ↑

正數 低位

高位 直接

補0 捨棄

b(-37)=

1101

1011

b>>

21101

1011

=>

1111

0110

↑ ↑

負數 低位

高位 直接

補1 捨棄

##三、常用舉例

​ 位運算是通過二進位制來表示的,所以只需要通過移動1就可以得到2的n次方的值。如:2^5 = 32

1

<<

50000

0001

<<5=

0010

0000

=32

​ 模擬2的n次方,乘或除以2就是左或右移1。如:16 / 2 = 8 ;4 * 2 = 8

16/2

=80001

0000

>>1=

0000

1000=8

4*2=

80000

0100

<<1=

0000

1000

=8

​ 因為2的次方用二進位制來表示會成為1000…的形式,所以也可以通過按位與運算來進行取餘,因為凡是後面不為0的為對應的都是餘

數。如:9%4 = 9&3

9%4

=10000

1001

90000

00113--

-------

0000

0001

1

n&((1<

​ 因為在計算機中,負數是用補碼表示的,所以如果這個數是負數,對這個數取反+1,就相當於還原了他的原碼,也就是求出了這個

負數的絕對值。所以對於乙個負數n,利用~a+1就可以得到他的絕對值。

​ 對於任何數,異或0會保持不變,異或1會改變,而上面判斷正負得到的是0和-1(也就是全0和全1),這樣的話再通過位運算來簡化一

下,將m設為n>>31(得到n的符號),然後用n^m,這樣就能保證正數不變,負數改變。然後再來處理後面的+1,我們已經知道正數m

為0,負數m為1,所以再在後面減去乙個m就可以得到乙個求絕對值的通式了

負數: b =

~b+1

;通式:

m=n>>31;

return

((n^m)

-m);-12

0000

1100

121111

0100-12

1111

1111-1

----

----

- 異或

0000

1011

11

​ 在計算機中,對於int型的最大值,也就是符號位為0,其餘位賦值為1,這樣直接(1<<31)-1就可以得到。同樣的,對於int型的最小

值,也就是符號位為1,其餘位賦值為0,這樣用(1<<31)直接可以得到答案。

(

1<<31)

-1;//int的最大值(1

<<31)

;//int的最小值

​ 二進位制最後一位決定了數字的奇偶性,直接按位與1就可以判斷出這個數的奇偶性了。

if

(n&1

)else

​ 因為二進位制的第一位為這個數的符號,所以只需要把第乙個數提取出來就可以知道正負了。負數右移完得-1,正數右移完得0。

if

((n>>31)

+1)else

​ 利用負數的補碼表示原則可以輕鬆解決這個問題。

i =

~i +

1;

##四、高階應用

a^

=b;b^

=a;a^

=b;

###2、rgb色彩分離

var 24bitcolor:uint =

0xff00cc

;var r:uint =

24bitcolor >>16;

var g:uint =

24bitcolor >>8&

0xff

;var b:uint =

24bitcolor &

0xff

;

var r:uint =

0xff

;var g:uint =

0x00

;var b:uint =

0xcc

;var 24bitcolor:uint = r <<

16| g <<

8| b;

總結 C 真是博大精深(一)

c 的輸入 輸出和非物件導向的一些特性 最終解釋權歸原文作者所有,侵權必究 1 c 語言是c語言的超集,c語言中的表示式 語句 函式等在c 中仍然可以使用,c 語言是物件導向的語言,但是也包含一些非物件導向的特性。2 include是編譯預處理命令,用於指示編譯器在進行程式預處理時,將檔案iostr...

總結 C 真是博大精深(三)

派生類與繼承 最終解釋權歸原文作者所有,侵權必究 1 繼承是物件導向程式設計的重要特徵之一,通過繼承,可以實現 重用。在c 中,繼承就是利用已有的類,通過派生的方式產生新的類。新類不但繼承了已有類的屬性和方法,而且可以增加新的屬性和方法。2 在c 中,可以在已有類的基礎上構建新類,這個新類繼承了已有...

總結 C 真是博大精深(一)

c 的輸入 輸出和非物件導向的一些特性 最終解釋權歸原文作者所有,侵權必究 1 c 語言是c語言的超集,c語言中的表示式 語句 函式等在c 中仍然可以使用,c 語言是物件導向的語言,但是也包含一些非物件導向的特性。2 include是編譯預處理命令,用於指示編譯器在進行程式預處理時,將檔案iostr...