五、位操作符
✅位操作符有:
& | ^ |
//按位与 //按位或 //按位异或 |
🚨注:他们的操作数必须是整数。
1. 按位与运算(AND)
✅按位与运算符为 &。其功能是对两个二进制数的每一个二进位进行与运算。
& 按位与: 两个条件同时为真(1)的情况下,运算结果为真,换句话说就是两个条件都是1才为1,否则为0。
1 & 1 = 1
1 & 0 = 0
0 & 1 = 0
0 & 0 = 0
2. 按位或运算(OR)
✅按位或运算符为 |。其功能对两个二进制数的每一个二进位进行或运算。
| 按位或 :任意一个条件为真(1)的情况下,运算结果为1,就是只要有一个1则为1,否则为0。
1 | 1 = 1
1 | 0 = 1
0 | 1 = 1
0 | 0 = 0
3. 按位异或运算(XOR)
✅按位异或运算符为 ^。其功能是对两个二进制数的每一个二进位进行异或运算。
^ 按位异或 :两个条件中只有一个条件为真(1)的情况下,运算结果为真。也就是说,相异才为 真,相同则为假。
0 ^ 0 = 0
1 ^ 0 = 1
0 ^ 1 = 1
1 ^ 1 = 0
4. 取反运算(NOT)
✅取反运算符为 ~。其功能是对一个二进制数的每一个二进位进行取反运算。
取反运算规则:使数字 1 变为 0,0 变为 1。
~0 = 1
~1 = 0
5. 位运算的应用
(1)判断整数奇偶
🍔一个整数,只要是偶数,其对应二进制数的末尾一定为 0;只要是奇数,其对应二进制数的末尾一定为 1。所以,我们通过与 1 进行按位与运算,即可判断某个数是奇数还是偶数。
(x & 1) == 0 为偶数。
(x & 1) == 1 为奇数
(2)二进制数选取指定位
🍔如果我们想要从一个二进制数 X中取出某几位,使取出位置上的二进位保留原值,其余位置为 0,则可以使用另一个二进制数 Y ,使该二进制数上对应取出位置为 1,其余位置为 0。然后令两个数进行按位与运算(X & Y),即可得到想要的数。
(3)将指定位设置为 1
🍔如果我们想要把一个二进制数 X中的某几位设置为 1,其余位置保留原值,则可以使用另一个二进制数 Y,使得该二进制上对应选取位置为 1,其余位置为 0。然后令两个数进行按位或运算(X | Y),即可得到想要的数。
(4)反转指定位
🍔如果我们想要把一个二进制数 X 的某几位进行反转,则可以使用另一个二进制数 Y ,使得该二进制上对应选取位置为 1,其余位置为 0。然后令两个数进行按位异或运算(X ^ Y),即可得到想要的数。
(5)交换两个数 —— 不借助第三变量
🍔通过按位异或运算可以实现交换两个数的目的(只能用于交换两个整数)。
#include <stdio.h> int main() { int a = 10; int b = 20; a = a^b; b = a^b; a = a^b; printf("a = %d b = %d\n", a, b); return 0; }
(6)将二进制最右侧为 1 的二进位改为 0
🍔如果我们想要将一个二进制数 X 最右侧为 1 的二进制位改为 0,则只需通过 X & (X - 1) 的操作即可完成。
(7)计算二进制中二进位为 1 的个数
🍔从“将二进制最右侧为 1 的二进位改为 0 ”中得知,通过 X & (X - 1) 我们可以将二进制 X 最右侧为 1 的二进制位改为 0,那么如果我们不断通过 X & (X - 1) 操作,最终将二进制 X 变为 0,并统计执行次数,则可以得到二进制中二进位为 1 的个数。
#include <stdio.h> int TheOne(int x) { int count = 0; while(x) { x = x & (x - 1); count++; } return count; }
(8)判断某数是否为 2 的幂次方
🍔通过判断 X & (X - 1) == 0 是否成立,即可判断 X 是否为 2 的幂次方。这是因为:
🔴凡是 2 的幂次方,其二进制数的某一高位为 1,并且仅此高位为 1,其余位都为 0。
🔴不是 2 的幂次方,其二进制数存在多个值为 1 的位。
🍔接下来我们使用 X & (X - 1) 操作,将原数对应二进制数最右侧为 1 的二进位改为 0 之后,得到新值:
如果原数是 2 的幂次方,则通过 X & (X - 1) 操作之后,新值所有位都为 0,值为 0。
如果该数不是 2 的幂次方,则通过 X & (X - 1) 操作之后,新值仍存在不为 0 的位,值肯定不为 0。
💧所以我们可以通过是否为 0 即可判断该数是否为 2 的幂次方。
六、赋值操作符
🍔赋值操作符是一个很好用的操作符,他可以让你得到一个你之前不满意的值。也就是你可以给自己重新赋值
复合赋值符
1、 + =
2、 - =
2、 * =
4、 / =
5、 %=
6、 >>=
7、 <<=
8、 &=
9、 |=
10、^=
💧这些运算符都可以写成复合的效果
int x = 10; x = x+10; x += 10;//复合赋值 //其他运算符一样的道理。这样写更加简洁。
七、单目操作符
! | 逻辑反操作 |
- | 负值 |
+ | 正值 |
& | 取地址 |
sizeof | 操作数的类型长度(以字节为单位) |
~ | 对一个数的二进制按位取反 |
- - | 前置、后置- - |
+ + | 前置、后置++ |
* | 间接访问操作符(解引用操作符) |
(类型) | 强制类型转换 |
八、关系操作符
> | 用于比较左右两个值的大小 |
>= | 用于比较左右两个值的大小 |
< |
用于比较左右两个值的大小 |
<= |
用于比较左右两个值的大小 |
! = | 用于测试“不相等” |
== | 用于测试“相等” |
这些关系运算符比较简单,但是我们要注意一些运算符使用时候的陷阱。
🚨警告:在编程的过程中== 和=不小心写错,导致的错误