1. 单个运算符:&
和 |
这些是位运算符,用于操作二进制位。
&
(按位与)
- 对应的二进制位都为1,结果才为1,否则为0。
- 示例:
int a = 5; // 二进制:0101 int b = 3; // 二进制:0011 int c = a & b; // 结果:0001 (1)
|
(按位或)
- 对应的二进制位只要有一个为1,结果就为1。
- 示例:
int a = 5; // 二进制:0101 int b = 3; // 二进制:0011 int c = a | b; // 结果:0111 (7)
2. 双运算符:&&
和 ||
这些是逻辑运算符,用于布尔值(或逻辑表达式)的运算。
&&
(逻辑与)
- 两个表达式都为真时,结果为真;否则为假。
- 短路特性:如果第一个表达式为假,后面的表达式不会被计算。
- 示例:
int a = 5, b = 0; if (a > 0 && b > 0) { // 条件为假,因为 b > 0 为假 }
||
(逻辑或)
- 只要有一个表达式为真,结果为真。
- 短路特性:如果第一个表达式为真,后面的表达式不会被计算。
- 示例:
int a = 5, b = 0; if (a > 0 || b > 0) { // 条件为真,因为 a > 0 为真 }
主要区别
运算符 | 类型 | 应用范围 | 特性 |
---|---|---|---|
& | 按位与运算 | 位操作 | 无短路特性 |
` | ` | 按位或运算 | 位操作 |
&& | 逻辑与运算 | 布尔逻辑 | 有短路特性 |
` | ` | 逻辑或运算 |
综合示例
#include <stdio.h>
int main() {
int a = 5; // 二进制:0101
int b = 3; // 二进制:0011
int c;
// 按位运算
c = a & b; // 结果:1(二进制:0001)
printf("a & b = %d\n", c);
c = a | b; // 结果:7(二进制:0111)
printf("a | b = %d\n", c);
// 逻辑运算
if (a > 0 && b > 0) {
printf("Both a and b are positive.\n");
}
if (a > 0 || b > 0) {
printf("At least one of a or b is positive.\n");
}
return 0;
}
输出:
a & b = 1
a | b = 7
Both a and b are positive.
At least one of a or b is positive.
短路规则
-
&&
(逻辑与)- 如果左边的表达式为假,整个表达式一定为假,因此右边的表达式不会被求值。
- 原因:
false AND anything
总是false
。
示例:
int a = 0; if (a != 0 && (10 / a > 1)) { // 右边的表达式不会执行 printf("Condition is true.\n"); } else { printf("Condition is false.\n"); }
输出:
Condition is false.
**说明:**由于
a != 0
为假,10 / a > 1
不会被计算,因此避免了除以零的错误。
-
||
(逻辑或)- 如果左边的表达式为真,整个表达式一定为真,因此右边的表达式不会被求值。
- 原因:
true OR anything
总是true
。
示例:
int a = 1; if (a == 1 || (10 / a > 1)) { // 右边的表达式不会执行 printf("Condition is true.\n"); }
输出:
Condition is true.
实际应用场景
短路求值常用于避免不必要的计算或者防止错误,比如在检查指针或避免除以零时非常有用。
避免空指针访问
char *ptr = NULL;
if (ptr && ptr[0] == 'A') { // 如果 ptr 为 NULL,ptr[0] 不会被访问
printf("First character is A.\n");
}
避免除以零
int a = 0, b = 10;
if (a != 0 && b / a > 1) { // 避免了 b / a 的计算
printf("Division is valid.\n");
}
注意
短路求值仅适用于逻辑运算符 &&
和 ||
。位运算符 &
和 |
不具备短路特性,始终会计算两边的表达式。
示例对比:
int a = 0;
// 使用 &(无短路特性)
if (a != 0 & (10 / a > 1)) { // 会计算 10 / a,导致错误
printf("This will cause an error.\n");
}
结果:程序崩溃(除以零错误)