C语言中&
和&&
有什么区别?
我的老师给了我一个例子:
int a = 8;
int b = 4;
printf("a & b = %d\n", a & b);
printf("a && b = %d\n", a && b);
输出:
a & b = 0;
a && b = 1;
我不确定为什么在某种情况下会返回true,在另一种情况下会返回false。
C语言中&
和&&
有什么区别?
我的老师给了我一个例子:
int a = 8;
int b = 4;
printf("a & b = %d\n", a & b);
printf("a && b = %d\n", a && b);
输出:
a & b = 0;
a && b = 1;
我不确定为什么在某种情况下会返回true,在另一种情况下会返回false。
&
是按位与,&&
是逻辑与。
表达式x && y
将在x
和y
都为非零时返回1
,否则返回0
。请注意,如果x
为零,则y
将不会被评估。如果y
是带有副作用的表达式,则这将很重要。这种行为称为短路。
表达式x & y
将对x
和y
中的每个位执行按位运算。因此,如果x
以二进制表示为1010
,y
以二进制表示为1100
,那么x & y
将计算为1000
。请注意,x & y
的返回值不应解释为布尔值,即使可能可以。在早期的C语言中,运算符&&
不存在,因此使用&
来实现相同的目的。
一种解释方式是,您可以想象&
与在操作数的每个单独位上应用&&
相同。
&
的优先级比&&
低,尽管直觉告诉我们应该相反。比较运算符也是如此,如<
、<=
、==
、!=
、>=
和>
。这源于C语言没有逻辑运算符&&
和||
时使用的按位运算符。当时这样做很有意义,但是添加逻辑运算符后就不再是这样了。Kernighan和Ritchie承认这样做更有意义,但他们没有修复它,因为这会破坏现有的代码。
我不确定为什么在一个场景中会返回true,在另一个场景中会返回false。
x & y
的返回值根本就不应该被视为布尔值。但是,它可以(取决于代码的编写方式)被视为布尔数组。如果你有两个整数flags1
和flags2
,那么flags1&flags2
的结果将指示在both flags1
和flags2
中切换的标志。&
运算符的优先级低于比较运算符 <
, <=
, ==
, !=
, >=
, >
。请参考 cyclaminist 对最初问题的评论,例如 a & b == 1
被视为 a & (b == 1)
。最初 C 语言没有逻辑运算符,因此使用二进制运算符作为替代。当逻辑运算符如 &&
和 ||
加入到 C 语言时,二进制运算符 &
, |
, and ^
的优先级应该升高,但 Kernighan 和 Ritchie 担心会影响向后兼容性。 - rcgldr&
运算符对其整数操作数执行按位与操作,生成一个整数结果。因此,(8 & 4)
等同于(0b00001000 bitand 0b00000100)
(为了清晰起见使用二进制记法,该标准C中不存在),其结果为0b00000000
或0
。
&&
运算符对其布尔操作数执行逻辑与操作,生成一个布尔结果。因此,(8 && 4)
等同于((8 != 0) and (4 != 0))
或(true and true)
,其结果为true
。&& (逻辑与运算符) - 左右操作数都是
boolean
表达式。 如果两个操作数都为非零值,则条件为真。
>
& (按位与运算符) - 左右操作数均为
integral
类型。按位AND运算符将一个位复制到结果中,如果这个位在两个操作数中都存在。
在您老师的例子中,a && b
的左操作数4
和右操作数8
都是非零值。 因此条件将成为真。
在您老师的另一个例子中,a & b
的左操作数4
或0100
和右操作数8
或01000
没有将任何位复制到结果中。 这是因为两个操作数中都没有相同的设置位。
我很惊讶老师没有展示更多运用更大数字的例子:
语句:
printf("14 & 18 = %d\n", 14 & 18);
printf("14 && 18 = %d", 14 && 18);
输出:
14 & 18 = 2
14 && 18 = 1
语句:
printf("300 & 400 = %d\n", 300 & 400);
printf("300 && 400 = %d", 300 && 400);
输出:
300 & 400 = 256
300 && 400 = 1
& 是位运算符,表示“与”,而&&是逻辑运算符。例如,如果您想使用两个数字并且想要使用位运算符,可以写成&。 如果您想使用短语并且想要在逻辑上处理它们,可以使用&&。
&
代表按位与,&&
代表逻辑与。 - Fred Larson_Bool
类型和stdbool.h
,其中bool
被定义为_Bool
的 typedef。 - Christian Gibbons