1 按位与&
按位运算就是二进制层面每个比特的运算 。一个Bit位只有 0 和 1 两个取值,只有参与&运算的两个位都为 1 时,结果才为 1,否则为 0。例如1&1为 1,0&0为 0,1&0也为 0,这和逻辑运算符&相同。
C语言中不能直接使用二进制,&两边的操作数可以是十进制、八进制、十六进制,实际上在内存中他们最终都是以二进制形式存储,&就是对这些内存中的二进制位进行运算。其他的位运算符也是相同的道理。内存中1和3按位与运算
1 0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 0001
3 0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 0011
1&3 0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 0001
也就是说,按位与运算会对参与运算的两个数的所有二进制位进行&运算,1 & 3的结果为 1。
printf("%d", 1&3);
1
按位与的应用, 可以让一个数x的某个位置是0, 我只需要让x与一个该位置是0其他位置是1的数做按位与运算, 1的位置不变,0的位置不管是什么都变成0 .
2 按位或|
按位取或就是两个位置有一个1则为1,否则为0. 可以用于将某一位变成0, 或将两个数拼起来
1 0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 0001
3 0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 0011
1|3 0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 0011
printf("%d\n", 1|3 );
3
也就是说,1| 3的结果为3。
3 按位取反~
取反运算符为单目运算符,右结合性,作用是对参与运算的二进制位取反。
1 0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 0001
~1 1111 1111 -- 1111 1111 -- 1111 1111 -- 1111 1110
printf("%d\n", ~1);
-2
也就是说1按位取反为有符号的-2
4 按位异或^
参与^ 运算两个二进制位不同时,结果为 1,相同时结果为 0。例如0\ ^ 1为1,0^ 0为0,1^1为0。
所以一个数做对同一个数做两次异或等于什么都没做。 相当于一个简单的加密了。
1 0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 0001
3 0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 0011
2=1^3 0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 0010
1=2^3 0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 0001
5 左移<<
i<<j 表示i二进制中所有的为向左移动j个位置, 右边补0 .
1 0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 0001
4=1<<2 0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 0100
x左移n为相当于 x = x ∗ 2 n x =x*2^n x=x∗2n
printf("%d\n", 1<<2);
4
6 右移>>
i>>j 表示i二进制中所有的为向右移动j个位置, 无符号的类型右边填入0, 有符号的数符号不变.
x右移n为相当于
x
=
x
∗
2
−
n
x =x*2^{-n}
x=x∗2−n
4 0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 0100
1=4>>2 0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 0001
printf("%d\n", 4>>2);
1
另外,c中与、或、非中逻辑运算分别是&&, ||, ! 不要弄混了。