【问题标题】:Will this expression evaluate to true or false (1 or 0) in C?这个表达式在 C 中的计算结果是真还是假(1 或 0)?
【发布时间】:2023-01-12 00:22:39
【问题描述】:
#include<stdio.h>
int main()
{
    int a=4;
    int b=4;
    int c= a++ < ++b? 1 : 0;
    
    printf ("%d",c);
}

已知在?处有一个序列点,这意味着前缀和后缀操作都必须在该点完成。还知道(?) b 在比较之前递增。但是,a是在比较前还是比较后自增?

如果它在 &lt; 测试之前递增,则布尔值评估为 false,c 设置为 0,否则为 true,c 设置为 1。在我的编译器中,它评估为 true,这意味着 @ 987654328@在与c设置为1的比较运算后执行。

这种行为是规范的一部分吗?

我修改为

#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。后缀必须在 ? 之前完成,但这是否真的确保它发生在比较 &lt; 之后?

【问题讨论】:

  • a 比较后递增。后递增,因此使用未递增的值。
  • int c= a++ &lt; ++b? 1 : 0; 可以直接替换为 int c= a++ &lt; ++b;,尽管我可能会使用 int c= (a++ &lt; ++b); 来明确将布尔比较结果分配给 c 的意图。

标签: c postfix-operator


【解决方案1】:

a++返回a的值增量。 ++b返回b的值增量。因此这计算为1

由于在表达式中 ab 都没有多次使用,因此不存在未定义的行为。

【讨论】:

  • 你好,你能给我一些关于后缀运算符的正式规则的资源吗?
  • @user2277550 相关:sequence points in c。后增量发生在正在读取的值和下一个序列点之间的某个未指定时刻。
  • @WeatherVane 但是那个序列点是'?',对吧?
【解决方案2】:

还知道(?) b 在比较之前递增。 但是,a是在比较之前还是之后递增的?

这是一个微妙的点,但重要的是要了解什么是真的在这里进行。

子表达式 a++++b 都做事物。他们计算一个新值用于周围的表达式,他们更新他们正在操作的变量的存储值。

所以 a++ 这样做:

  1. 它将a (4) 的旧值输出给周围的表达式
  2. 它将新值 (5) 存储到a

    ++b 这样做:

    1. 它向周围的表达式产生新值b(4+1 或 5)
    2. 它将新值 (5) 存储到b

      请注意,在这两种情况下,'<' 运算符关心的都是第一件事。而且,在这两种情况下,事情 1 都是绝对定义,它不依赖于时间。

      时间是事情 2 的来源。我们不知道,确切地说,新值何时被存储回a。我们也不知道新值何时被存储回b。我们所知道的是,这些存储将在下一个序列点之前的某个时间发生(正如您正确注意到的那样,在本例中是 ? 运算符的 ? 部分)。

【讨论】:

    猜你喜欢
    • 2016-10-18
    • 2019-07-31
    • 2012-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-30
    相关资源
    最近更新 更多