C中的逻辑表达式误解
Logical Expressions in C misunderstanding
所以,我在编写一些代码时,在我的程序的一部分中得到了意外的输出,这扰乱了整个系统。
我设法将问题提取并简化为基本的逻辑表达式。比方说:
int i = 1, j = 1, k = 0;
printf("%d\n", ++i || ++j && k);
printf("%d, %d, %d\n", i, j, k);
return 0;
这个程序的输出是:
1
2
1
0
我在想,由于 ||
运算符的短路性质,j
的值没有增加到 2
。但是我很困惑第一个 "%d"
的值是 1
。对于 return 1
的 &&
语句,k
的值不应该是非零的吗?或者根本不执行此语句,因为 ++i || ++j
不是 0
,因此 return 是 1
?
- 我知道
&&
是合乎逻辑的and,和expr1 && expr2 的值为 1,如果 expr1 && expr2 的值 both 非零。
任何澄清将不胜感激,请原谅这个问题的基本性质。
&&
的优先级高于 ||
。
(见 https://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B )
所以
++i || ++j && k
是
++i || (++j && k)
如果第一个运算符为真,则 和 ||
短路,如 6.5.14p4 。
如果您使用 gcc
或 clang
并使用 -Wall
编译代码,编译器会提示您将这些括号放在那里。听从这个建议可能是个好主意,因为有些人会对优先顺序感到困惑(我听说)。
++i || ++j && k
计算为 1(真),因为 i 等于 2 (++1),(++j && k) 未计算,因为短路。
来自 C 标准(6.5.14 逻辑或运算符)
3 The || operator shall yield 1 if either of its operands compare
unequal to 0; otherwise, it yields 0. The result has type int.
这个表达式
++i || ++j && k
等同于
++i || ( ++j && k )
并且根据标准中的引用,表达式 returns 整数值 1 因为 ++i
不等于零。子表达式 ( ++j && k )
未计算。
运算符优先。 &&
的优先级高于 ||
。
你的表达方式是一样的:++i || (++j && k)
++i
为TRUE
,括号不再求值
所以,我在编写一些代码时,在我的程序的一部分中得到了意外的输出,这扰乱了整个系统。
我设法将问题提取并简化为基本的逻辑表达式。比方说:
int i = 1, j = 1, k = 0;
printf("%d\n", ++i || ++j && k);
printf("%d, %d, %d\n", i, j, k);
return 0;
这个程序的输出是:
1
2
1
0
我在想,由于 ||
运算符的短路性质,j
的值没有增加到 2
。但是我很困惑第一个 "%d"
的值是 1
。对于 return 1
的 &&
语句,k
的值不应该是非零的吗?或者根本不执行此语句,因为 ++i || ++j
不是 0
,因此 return 是 1
?
- 我知道
&&
是合乎逻辑的and,和expr1 && expr2 的值为 1,如果 expr1 && expr2 的值 both 非零。
任何澄清将不胜感激,请原谅这个问题的基本性质。
&&
的优先级高于 ||
。
(见 https://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B )
所以
++i || ++j && k
是
++i || (++j && k)
如果第一个运算符为真,则 和 ||
短路,如 6.5.14p4 。
如果您使用 gcc
或 clang
并使用 -Wall
编译代码,编译器会提示您将这些括号放在那里。听从这个建议可能是个好主意,因为有些人会对优先顺序感到困惑(我听说)。
++i || ++j && k
计算为 1(真),因为 i 等于 2 (++1),(++j && k) 未计算,因为短路。
来自 C 标准(6.5.14 逻辑或运算符)
3 The || operator shall yield 1 if either of its operands compare unequal to 0; otherwise, it yields 0. The result has type int.
这个表达式
++i || ++j && k
等同于
++i || ( ++j && k )
并且根据标准中的引用,表达式 returns 整数值 1 因为 ++i
不等于零。子表达式 ( ++j && k )
未计算。
运算符优先。 &&
的优先级高于 ||
。
你的表达方式是一样的:++i || (++j && k)
++i
为TRUE
,括号不再求值