&和&&在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。
gzjq41n41#
&是 * 按位与 *,&&是 * 逻辑与 *。如果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和里奇承认这会更有意义,但他们没有修复它,因为这会破坏现有的代码。我不知道为什么这会在一个场景中返回true,而在另一个场景中返回false。x & y的返回值 * 根本不应该 * 被视为布尔值。然而,它可以(取决于代码的编写方式)被视为布尔数组。如果你有两个整数,flags1和flags2,那么flags1 & flags2的结果将表示哪些标志在 * flags1和flags2中被切换。
x
y
x && y
1
0
x & y
1010
1100
1000
<
<=
==
!=
>=
>
||
flags1
flags2
flags1 & flags2
nbysray52#
&运算符对其整数操作数执行 * 位与 * 运算,产生整数结果。因此(8 & 4)是(0b00001000 bitand 0b00000100)(为了清楚起见,使用标准C中不存在的二进制表示法),结果是0b00000000或0。&&运算符对其布尔操作数执行 * 逻辑与 * 运算,产生布尔结果。因此(8 && 4)等效于((8 != 0) and (4 != 0))或(true and true),其结果为true。
(8 & 4)
(0b00001000 bitand 0b00000100)
0b00000000
(8 && 4)
((8 != 0) and (4 != 0))
(true and true)
true
332nm8kg3#
&&(逻辑与运算符)-左操作数和右操作数是boolean表达式。如果两个操作数都是非零,则条件为真。
boolean
〉
&(按位与运算符)-左右操作数为integral类型。二进制与运算符复制一个位到结果中,如果它存在于两个操作数中。
integral
在你老师的例子a && b中,左操作数4和右操作数8都是非零的,所以条件将为真。在你老师的另一个例子a & b中,左操作数4或0100和右操作数8或01000没有将任何位复制到结果中。这是因为两个操作数中没有公共设置位。
a && b
4
8
a & b
0100
01000
gab6jxml4#
我很惊讶老师没有展示更多的使用更大数字的例子:声明:
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
ercv8c1e5#
&是位运算符,而&&是逻辑运算符,例如,如果你使用两个数字,你想使用位运算符,你可以写&。如果你想使用短语,你想逻辑地对待它们,你可以使用&&。
5条答案
按热度按时间gzjq41n41#
&
是 * 按位与 *,&&
是 * 逻辑与 *。如果
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和里奇承认这会更有意义,但他们没有修复它,因为这会破坏现有的代码。我不知道为什么这会在一个场景中返回true,而在另一个场景中返回false。
x & y
的返回值 * 根本不应该 * 被视为布尔值。然而,它可以(取决于代码的编写方式)被视为布尔数组。如果你有两个整数,flags1
和flags2
,那么flags1 & flags2
的结果将表示哪些标志在 *flags1
和flags2
中被切换。nbysray52#
&
运算符对其整数操作数执行 * 位与 * 运算,产生整数结果。因此(8 & 4)
是(0b00001000 bitand 0b00000100)
(为了清楚起见,使用标准C中不存在的二进制表示法),结果是0b00000000
或0
。&&
运算符对其布尔操作数执行 * 逻辑与 * 运算,产生布尔结果。因此(8 && 4)
等效于((8 != 0) and (4 != 0))
或(true and true)
,其结果为true
。332nm8kg3#
&&(逻辑与运算符)-左操作数和右操作数是
boolean
表达式。如果两个操作数都是非零,则条件为真。〉
&(按位与运算符)-左右操作数为
integral
类型。二进制与运算符复制一个位到结果中,如果它存在于两个操作数中。在你老师的例子
a && b
中,左操作数4
和右操作数8
都是非零的,所以条件将为真。在你老师的另一个例子
a & b
中,左操作数4
或0100
和右操作数8
或01000
没有将任何位复制到结果中。这是因为两个操作数中没有公共设置位。gab6jxml4#
我很惊讶老师没有展示更多的使用更大数字的例子:
声明:
输出:
声明:
输出:
ercv8c1e5#
&是位运算符,而&&是逻辑运算符,例如,如果你使用两个数字,你想使用位运算符,你可以写&。如果你想使用短语,你想逻辑地对待它们,你可以使用&&。