提问人:user2277550 提问时间:1/11/2023 最后编辑:Vlad from Moscowuser2277550 更新时间:10/26/2023 访问量:188
此表达式在 C 中的计算结果为 true 还是 false(1 或 0)?
Will this expression evaluate to true or false (1 or 0) in C?
问:
#include<stdio.h>
int main()
{
int a=4;
int b=4;
int c= a++ < ++b? 1 : 0;
printf ("%d",c);
}
已知 处有一个序列点,这意味着前缀和后缀操作都必须在该点之前完成。此外,已知(?)在比较之前递增。但是,在比较之前还是之后递增??
b
a
如果它在测试之前递增,则布尔值的计算结果为 false 并设置为 0,否则为 true,设置为 1。在我的编译器中,它的计算结果为 true,这意味着在设置为 1 的比较操作之后执行。<
c
c
a++
c
但是,这种行为是规范的一部分吗?
我把它修改成
#include<stdio.h>
int main()
{
int a=4;
int b=4;
int d=2;
int c= a++ + d < ++b + d? 1 : 0;
printf ("%d",c);
}
它的计算结果仍为 1。后缀必须在 之前完成,但这真的能确保它在比较之后发生吗??
<
答:
a++
返回增量之前的值。 返回 after the increment 的值。因此,这减少到哪个减少到哪个为真,因此表达式的计算结果为 。a
++b
b
4 + 2 < 5 + 2
6 < 7
a++ + d < ++b + d ? 1 : 0
1
由于表达式中既没有使用,也没有多次使用,因此不存在未定义的行为。a
b
评论
a = (*p++) ?(*p++) : 0
在第一个 *p++
之后有一个序列点,这意味着在执行第二个实例时它已经递增。但是,在读取您的之前,它仍然不会发生:这将是预增量。c
a
b
<
<
c = a + d < (b+1) + d? 1 : 0
此外,已知 (?) b 在比较之前递增。 但是,在比较之前还是之后递增?
这是一个微妙的点,但重要的是要了解这里到底发生了什么。
两个子表达式 和 做两件事。它们计算要在周围表达式中使用的新值,并更新它们正在操作的变量的存储值。a++
++b
这也是这样做的:a++
- 它将 (4) 的旧值输出到周围的表达式中
a
- 它将一个新值 (5) 存储到 中。
a
并这样做:++b
- 它将 (4+1 或 5) 的新值输出到周围的表达式中
b
- 它将一个新值 (5) 存储到 中。
b
请注意,在这两种情况下,操作员关心的是事情 1。而且,在这两种情况下,事物 1 都是一个绝对的定义,它不依赖于时间。<
或者,换句话说,问“/是在比较之前还是之后递增的?”并不是真正的正确问题。价值观并参与比较,仅此而已。a
b
a
b+1
时机是事情 2.我们不知道,确切地说,新值何时被存储回 .我们也不知道新值何时被存储回 。我们所知道的是,这些存储将发生在下一个序列点之前的某个时间(正如您正确指出的,在本例中是三元运算符的一部分)。a
b
?
但没有什么取决于这些时间,所以这里没有未定义的行为。
当以下任一情况发生时,会出现未定义的行为
- 被修改的变量 ( 或 ) 在表达式中的其他位置也有其值独立使用,这意味着我们不知道该用法是使用旧值还是新值
a
b
- 同一个变量被修改了两次,这意味着我们不知道两次修改中的哪一个“胜”
但是,同样,这些问题在这里都没有发生,因此表达式是明确定义的。
评论
来自 C 标准(6.5.2.4 后缀递增和递减运算符)
2 postfix ++ 运算符的结果是操作数的值。 作为副作用,操作数对象的值会递增(即 是,将相应类型的值 1 添加到其中)。
所以在这个宣言中
int c= a++ < ++b? 1 : 0;
初始值设定项中使用的子表达式的值是操作数在其增量之前的值。a++
a
另一方面(C 标准(6.5.3.1 前缀递增和递减运算符))
2 前缀 ++ 运算符的操作数值递增。结果是递增后操作数的新值。
所以子表达式的值就是递增后的值。++b
b
因此,您实际上拥有
int c = 4 < 5 ? 1 : 0;
至于序列点,那么为了演示它,你可以写例如
int c = a++ < b++ ? a : b;
在这种情况下,变量在应用递增的副作用后将具有变量的值,即 。c
b
5
评论
a
在比较后递增。后递增,因此使用未递增的值。int c= a++ < ++b? 1 : 0;
可以直接替换为 ,尽管我可能会用它来使将布尔比较结果分配给 clear 的意图。int c= a++ < ++b;
int c= (a++ < ++b);
c
a
a++
a
a