概述
需要了解位运算,只需要明白,无论是正数还是负数,编译系统都是按照内存中存储的内容进行位运算,因此不要管什么符号位不符号位的,全都参与运算。
- 按位与 &:全1为1
- 按位或 |:有1为1
- 按位取反 ~:1变0,0变1
- 异或 ^ :相异得1,相同得0
- 左位移 << :高位溢出,低位补0
- 右位移 >> :1. 逻辑右移: 不管是否有符号位,都是高位补0,低位溢出。2.算数右移:对有符号数来说,低位溢出,高位补符号位;对无符号位来说,高位补0,低位溢出。有位移是逻辑位移还是算数位移取决于编译器。
举例
#include<stdio.h>
int main() {
//测试
printf("%d\n", -5 & 10);//结果是10
printf("%d\n", -5 | 10);//结果是-5
printf("%d\n", ~-5);//结果是-5
printf("%x\n", -5 ^ 10);//结果是1
printf("%d\n", (-1) >> 3);//结果是-1
}
/*
* -5 & 10
1111 1111 1111 1111 1111 1111 1111 1011 -5的补码
& 0000 0000 0000 0000 0000 0000 0000 1010 10的补码
---------------------------------------
0000 0000 0000 0000 0000 0000 0000 1010 结果--》10
* -5 | 10
1111 1111 1111 1111 1111 1111 1111 1011 -5的补码
| 0000 0000 0000 0000 0000 0000 0000 1010 10的补码
---------------------------------------
1111 1111 1111 1111 1111 1111 1111 1011 结果--》-5
* ~-5
1111 1111 1111 1111 1111 1111 1111 1011
---------------------------------------
0000 0000 0000 0000 0000 0000 0000 0100 结果--》4
* -5 ^ 10
1111 1111 1111 1111 1111 1111 1111 1011 -5的补码
^ 0000 0000 0000 0000 0000 0000 0000 1010 10的补码
---------------------------------------
1111 1111 1111 1111 1111 1111 1111 0001 结果--》fffffff1
* -1 >> 3
1111 1111 1111 1111 1111 1111 1111 1111 -1的补码
---------------------------------------
1111 1111 1111 1111 1111 1111 1111 1111 结果是--》-1
*/
通过右移的测试,我使用的VS2019自带的编译器使用的是算数位移。