C语言中 & 和 && 的区别是什么?

16

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。


4
&代表按位与,&&代表逻辑与。 - Fred Larson
11
如果你没有找到这两个运算符的规范说明,那么你肯定需要提升自己的搜索技巧!请注意,“definitively”可译为“肯定地、明确地”,根据上下文可以选择适当的翻译。 - too honest for this site
1
@hyde C99 添加了 _Bool 类型和 stdbool.h,其中 bool 被定义为 _Bool 的 typedef。 - Christian Gibbons
4
我不认为这个问题太宽泛了。它很容易回答。如果没有合适的重复问题,我们应该直接回答它。 - Fred Larson
@FredLarson 好的,问题已经重新开放。请开始吧 :) - machine_1
显示剩余13条评论
5个回答

22

&按位与&&逻辑与

表达式x && y将在xy都为非零时返回1,否则返回0。请注意,如果x为零,则y将不会被评估。如果y是带有副作用的表达式,则这将很重要。这种行为称为短路

表达式x & y将对xy中的每个位执行按位运算。因此,如果x以二进制表示为1010y以二进制表示为1100,那么x & y将计算为1000。请注意,x & y的返回值不应解释为布尔值,即使可能可以。在早期的C语言中,运算符&&不存在,因此使用&来实现相同的目的。

一种解释方式是,您可以想象&与在操作数的每个单独位上应用&&相同。

请注意,&的优先级比&&低,尽管直觉告诉我们应该相反。比较运算符也是如此,如<<===!=>=>。这源于C语言没有逻辑运算符&&||时使用的按位运算符。当时这样做很有意义,但是添加逻辑运算符后就不再是这样了。Kernighan和Ritchie承认这样做更有意义,但他们没有修复它,因为这会破坏现有的代码。

我不确定为什么在一个场景中会返回true,在另一个场景中会返回false。

x & y的返回值根本就不应该被视为布尔值。但是,它可以(取决于代码的编写方式)被视为布尔数组。如果你有两个整数flags1flags2,那么flags1&flags2的结果将指示在both flags1flags2中切换的标志。

如果x和y都不为零,则应该是“if both x and y are non-zero”。可选地,“&与x和y中对应位的按位乘法或按位二进制and相同”。 - rcgldr
& 运算符的优先级低于比较运算符 <, <=, ==, !=, >=, >。请参考 cyclaminist 对最初问题的评论,例如 a & b == 1 被视为 a & (b == 1)。最初 C 语言没有逻辑运算符,因此使用二进制运算符作为替代。当逻辑运算符如 &&|| 加入到 C 语言时,二进制运算符 &, |, and ^ 的优先级应该升高,但 Kernighan 和 Ritchie 担心会影响向后兼容性。 - rcgldr

6
&运算符对其整数操作数执行按位与操作,生成一个整数结果。因此,(8 & 4)等同于(0b00001000 bitand 0b00000100)(为了清晰起见使用二进制记法,该标准C中不存在),其结果为0b000000000&&运算符对其布尔操作数执行逻辑与操作,生成一个布尔结果。因此,(8 && 4)等同于((8 != 0) and (4 != 0))(true and true),其结果为true

4

&& (逻辑与运算符) - 左右操作数都是boolean表达式。 如果两个操作数都为非零值,则条件为真。

>

& (按位与运算符) - 左右操作数均为integral类型。按位AND运算符将一个位复制到结果中,如果这个位在两个操作数中都存在。

在您老师的例子中,a && b的左操作数4和右操作数8都是非零值。 因此条件将成为真。

在您老师的另一个例子中,a & b的左操作数40100和右操作数801000没有将任何位复制到结果中。 这是因为两个操作数中都没有相同的设置位。


0

我很惊讶老师没有展示更多运用更大数字的例子:

语句:

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

-1

& 是位运算符,表示“与”,而&&是逻辑运算符。例如,如果您想使用两个数字并且想要使用位运算符,可以写成&。 如果您想使用短语并且想要在逻辑上处理它们,可以使用&&。


1
欢迎来到 Stack Overflow。这个问题已经有了两个非常好的答案。这个新回答提供了任何之前未涉及的信息吗?请阅读[答案]。 - Chris

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接