位运算

&按位与运算

通常用来判断某位的值是否为0或者将某个数的低几位置0。使用时得注意数据类型的size大小

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void and_test(void){
int int_num = 17;
char char_num = 127;
printf("int_num & 7 value = %d\n",int_num & 7);
printf("int_num & 0xfffffff0 = %d\n",int_num & 0xfffffff0);
printf("int_num & 7 value = %d\n",char_num & 7);
printf("int_num & 0xf0 = %d\n",char_num & 0xf0);
}
/*
int_num & 7 value = 1
int_num & 0xfffffff0 = 16
int_num & 7 value = 7
int_num & 0xf0 = 112
*/

|按位或运算

00,其它出10|0 = 0, 0 | 1 = 1, 1 | 1 = 1, 1 | 1 = 1;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void or_test(void){
int int_num = 17;
char char_num = 11;
printf("int_num | 7 value = %d\n",int_num | 7);
printf("int_num | 0xfffffff0 = %d\n",int_num | 0x7ffffff0);//最高位为符号位
printf("int_num | 7 value = %d\n",char_num | 7);
printf("int_num | 0xf0 = %d\n",char_num | 0xf0);
}
/*
int_num | 7 value = 23
int_num | 0xfffffff0 = 2147483633
int_num | 7 value = 15
int_num | 0xf0 = 251
*/

^按位异或运算

如果 a ^ b = c,那么c ^ b = a, c ^ a = b(穷举证明)0 ^ 1 = 1, 1 ^ 0 = 1, 0 ^ 0 = 0, 1 ^ 1 = 0

1
2
3
4
5
6
7
8
9
10
11
12
13
void XOR_test(void){
int a = 5, b = 7;
a ^= b;
b ^= a;
a ^= b;
}/*
a = 7, b = 5
a = 0101
b = 0111
a = a ^ b = 0101 ^ 0111 = 0010; == 2
b = a ^ b = 0010 ^ 0111 = 0101; == 5
a = a ^ b = 0010 ^ 0101 = 0111; == 7
*/

<<左移运算符(>>右移同理)

a << b意思是吧a左移b位高位丢弃,低位补零。实际上,左移n位,就等于把这个数✖️2^n。但是左移运算比乘法快很多。同时编译器规定移动操作时,符号位会根据原符号位补上右移等于把这个数➗2^n(向下取整)。

PS:位移运算时一位一位进行的,符号位被移动后会立刻按照规则(补上符号位会根据原符号位补上)

由于移动不是循环移动,因此移动到边界会直接丢掉

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void shift_left(void){
int int_1 = 15;// 0000 0000 0000 0000 0000 0000 0000 1111
short short_1 = -15;//1000 0000 0000 1111
unsigned short unshort = 0xffe0;//1111 1111 1110 0000
char c = 15;//0000 1111
int_1 >>= 2;
short_1 >>= 3;
unshort >>= 4;
c >>= 3;
printf("int_1 = %0x\n short_1 = %0x\n unshort = %0x \n c = %0x\n",int_1,short_1,unshort,c);
}/*
int_1 = 3
short_1 = fffffffe
unshort = ffe
c = 1
*/