c++学习 4 运算符及其应用技巧

一 按位与运算符

“&”按位与运算符,全1为1,有0则0

特点:和1相与保持不变,和0相与都变为0。

功能:将指定位置清0。

example:

   1000 1100

& 1100 1011

------------------------------

   1000 1000

unsigned int data;//目标:将1字节的data第3、4位清零。

data = data & 1110 0111;//注意,c++语言并不支持直接识别二进制数位做按位运算,必须得转换成十六进制。

data = data & 0xe7;//这才是正确的写法,但是难写并且可读性很低(十六进制的转换)。

//所以我们必须在十六进制的基础上优化写法,后续知识点补全后一起说

data &= 0xe7;//这个也行,而且写出来方便简洁。

 

二 按位或运算符

“|”按位或运算符,有1为1,全0才0

特点:和1相或都得1,和0相或保持不变。

功能:将指定位置至为1。

example:
    1000 1100

|   1100 1111

----------------------------

    1100 1111

unsigned int data;//data为1字节,将data的5、6位置为1,其他位不变。

data = data | 0110 0000;//在c++中,位数计数顺序是从右到左的。

data = data | 0x60;//而且也是需要十六进制才能被c++识别。

data |= 0x60;//简朴写法。

 

三 按位取反运算符

“~”按位取反运算符,0变1,1变0.

特点:取反码。

功能:配合按位与(&)和按位或(|)进行操作。

example:~1001 1100 == 0110 0011;

 

四 按位异或运算符

“^”按位异或运算符,相同位数为0,不同位数为1

特点:和1异或取反,和0异或保持不变。

功能:将指定位发生翻转。

example:

    1100 0011

^   1011 1111

-----------------------

      0111 1100

1011 1100 ^ 1111 0000 == 0111 1100

 

五 左移运算符

“<<”左移运算符,左边丢弃,右边补0。

注意:移动的位数不要超过自身位的宽度

example:

int data = 1011 0000;

data = data<<3;

cout<<data<<;//data等于1000 0000。

如果data=0000 0001=1,那么data<<1 = 0000 0010 =2=1*2^1;

以此类推,data << 2 = 0000 0100 = 4 =2^2;

data << 3 = 0000 1000 = 8 =2^3;

所以<<几位就是乘上2的几次方。

 

六 右移运算符

“>>”右移运算符,右边丢弃,左边补0或者补1。

注意:补0(逻辑右移)还是补1(算数右移)由编译器自己决定,用户无法自己决定。

无符号数:右边丢弃,左边补0。

正数:右边丢弃,左边补0。

负数:右边丢弃,左边补0(逻辑右移);

负数:右边丢弃,左边补1(算数右移)。

由五可知,data>>几位其实也就相当于除以2^x。

 

七 位运算符的综合应用

在书写按位运算符时,由于十六进制的限制导致我们无法快速解读出究竟是清0还是置1,以及操作位数是哪几位等等。所以我们需要借助特殊的写法来在十六进制的基础上提高位运算符的可读性。

example:

在按位与运算符中,我们做了“将data3、4位清0”的操作。

data &= 0xe7;//即为data &= 1110 0111;

我们来对1110 0111变形

1110 0111 == ~(0001 1000) == ~(0001 0000 | 0000 1000)//这一步重点理解!!!

== ~(0000 0001<<4 | 0000 0001<<3) == ~(0x01<<4 | 0x01<<3)

所以最后结果就可以写为

data &= ~(0x01<<4 | 0x01<<3);

不仅提高可读性,也降低了转换为十六进制的难度,可谓是一石二鸟。

同理可得,按位或运算符的例子里,data |= 0x60也可以因此转换。

data |= 0110 0000 == (0100 0000 | 0010 0000) == (0000 0001<<6 | 0000 0001<<5)

== (0x01<<6 | 0x01<<5)

所以也可以转换为 data |= (0x01<<6 | 0x01<<5);

总结:

1.有取反(~)是清0,无取反是置1

2.使用这种写法,不仅可以根据操作位数直接写出十六进制,而且大大提高可读性,降低了操作难度。

posted @ 2023-02-08 02:35  王博涵  阅读(80)  评论(0编辑  收藏  举报