不知不觉已经来这边第四天了,今天感觉巨累而且睡眠不是很好。今天上午讲了位运算符,位运算符有六种:&,|,^,<<,>>, ~。下面一一讲解。
①符号:&
格式:数据1&数据2
规则:将数据转成二进制补码
按照低位对齐,对不齐前面补0
"全1为1,有0则0"
规律:
如果想将一个数据的第n位置0,只需要将数据&(第n位是0其他位都是1的数)
如果想将一个数据的第n位和第n+1置0,只需要将数据&(第n位和第n+1位是0其他位都是1的数)
②符号:|
格式:数据1|数据2
规则:将数据转成二进制补码
按照低位对齐,对不齐前面补0
"有1则1,全0为0"
规律:如果想将一个数的第n位置1,只需要将数据|(第n位是1,其他位都是0的数)
如果想将一个数据的第n位和第n+1置1,只需要将数据|(第n位和第n+1位是1其他位都是0的数)
③符号:^
格式:数据 1 ^ b数据2
规则:将数据转成二进制补码
按照低位对齐,对不齐前面补0
"不同为1,相同为0"
④按位取反
符号:~
格式:~数据
规则:将数据转成二进制补码
按照数据类型的位数进行补齐
“所有位0变1,1变0
⑤按位左移
符号:<<
格式:数据<<位数
规则:将数据转成二进制补码
所有位整体左移,低位补0,高位溢出舍弃
规律:n<<m得到的结果就是n*2^m
左移一位扩大一倍就是*2
⑥按位右移
符号:>>
格式:数据>>位数
规则:将数据转成二进制补码
所有位整体右移,低位溢出舍弃,高位补符号位上的数据
一般用于数据分割。
下午是讲了位运算符的应用,还是上午那些运算符号。(前面一天提到了数都是以二进制的方式存在计算机的空间中)
- & 通常是置0。例如在unsigned int a = 0b1111 1111 1111 1111;的情况下,如果需要将a中的第五位置0,那么可以进行a & 0b1111 1111 1101 1111;的运算。输出的结果就是a = 0b1111 1111 1110 1111。还有一种简便的方法就是:a &= ~(1 << 5)。非常简便,下面来解释一下,1往左移了5位。也就是0000 0000 0000 0001变成了0000 0000 0001 0000。再进行~(取反)就会得到 1111 1111 1110 1111。再去进行&运算,就能得到和上面一样的结果了。还有一种用法就是判断某一位是0还是1,这边采用老师的数据:
unsignedinta=0x45f87980;
判断a的第5位是0还是1;
??????????????????????????1?????
&00000000000000000000000000100000
00000000000000000000000000100000
a&(1<<5);
如果结果!=0
{
对应位是1
}
否则
{
对应位上是0
}
代码:
unsignedinta=0x45f87930;
if((a&(1<<5))!=0)
{
printf("1");
}
else
{
printf("0");
}
- | 通常是置1。例如在unsigned int a = 0b0000 1111 0000 1111;的情况下,如果需要将a中的第五位置1,那么可以进行a | 0b0000 0000 0001 0000;的运算。输出的结果就是a = 0b0000 1111 0001 1111。还有一种简便的方法就是:a |= (1 << 5)。非常简便,下面来解释一下,1往左移了5位。也就是0000 0000 0000 0001变成了0000 0000 0001 0000。再去进行|运算,就能得到和上面一样的结果了。
- ^ 通常是位反转,0变成1,1变成0的操作。例如在unsigned int a = 0b1111 1111 1111 1111;的情况下,如果需要将a中的第五位置反面,那么可以进行a ^ 0b0000 0000 0001 0000;的运算。输出的结果就是a = 0b1111 1111 1110 1111。再反面一次又变回来了,还有一种简便的方法就是:a ^= (1 << 5)。非常简便,下面来解释一下,1往左移了5位。也就是0000 0000 0000 0001变成了0000 0000 0001 0000。再与a进行异或就会得到 1111 1111 1110 1111,这就反面了。如果再来一次^运算,就能得到和原来一样的数据了。
- 置于01或者10。有两种思路,
思路1:分开置0置1
思路2:先将这两位清0,然后再重置01或者10
将a的第5位和第4位置01
将a的第5位和第4位置00a&=~(3<<4);
将a的第5位和第4位重置01a|=(1<<4);
将a的第5位和第4位置10
将a的第5位和第4位置00a&=~(3<<4);
将a的第5位和第4位重置10a|=(1<<5);或者a|=(2<<4);
最后总结一下位运算公式:
前提:第几位置0或者置1是从最低位作为第0位开始数
①、将a的第n位置1,公式:a|=(1<<n);
例如:将端口8配置成开漏模式:GPIO8->OTYPER|=(1<<8);
②、将a的第n位和第n+1位同时置1,公式:a|=(3<<n);
③、将a的第n位置0,公式:a&=~(1<<n);
④、将a的第n位和第n+1位同时置0,公式:a&=~(3<<n);
⑤、判断a的第n位是0还是1,公式:a&(1<<n)看结果,如果结果!=0,第n位是1,否则第n位是0
⑥、将a的第n+1位和第n位置01或者10
先清00a&=~(3<<n);
在重置01或者10a|=(1<<n);或者a|=(2<<n);
⑦、将a的第n位0变1,1变0;
a^=(1<<n);
今天又是学习的一天!!!