?: 运算符在 C 中究竟是如何工作的?

J0S*_*J0S 10 c syntax increment conditional-operator post-increment

我有一个问题,编译器如何对以下代码进行操作:

#include<stdio.h>

int main(void)
{
  int b=12, c=11;
  int d = (b == c++) ? (c+1) : (c-1);
  printf("d = %i\n", d);
}
Run Code Online (Sandbox Code Playgroud)

我不知道为什么结果是???d = 11.

Eri*_*hil 6

int d = (b == c++) ? (c+1) : (c-1);

  • 的值c++是 11 的当前值c。单独c增加到 12。
  • b == 11是假的,因为b是 12。
  • 因为(b == c++)是假的,(c-1)被使用了。此外,c到 12的增量必须在此时完成。
  • 因为c是 12,所以c-1是 11。
  • d 被初始化为那个值,11。


Vla*_*cow 5

根据 C 标准(6.5.15 条件运算符)

4 评估第一个操作数;在它的求值和第二个或第三个操作数(以求值为准)的求值之间有一个序列点。仅当第一个操作数不等于 0 时才计算第二个操作数;仅当第一个操作数等于 0 时才计算第三个操作数;结果是第二个或第三个操作数的值(以求值者为准),转换为下面描述的类型。110)

所以在这个声明的初始化表达式中

int d = (b == c++) ? (c+1) : (c-1);
Run Code Online (Sandbox Code Playgroud)

将变量b与变量的值进行比较,c因为后递增运算符在递增之前返回其操作数的值。

由于这些值彼此不相等(b设置为 12 而c设置为 11)然后(c-1)评估子表达式。

根据报价,在评估运营商的条件后有一个序列点。这意味着在条件评估后c具有12将后增量运算符应用于变量后的值c。结果变量 d 由值1( 12 - 1)初始化。

  • 唯一正确的答案 - 这种特定情况必须通过提及“?:”中的序列点来回答。因为通常在 C 中,将 ++ 与同一操作数上的其他操作组合是未定义的行为。这段代码只能按预期工作,因为 `?:` 有各种特殊的雪花规则。 (2认同)

Ody*_*eus 4

转换为常规的 if 语句,您的代码将如下所示:

int b=12, c=11;
int d;

if (b == c++)
   d = c+1;
else
   d = c-1;
Run Code Online (Sandbox Code Playgroud)

这里的线索是检查条件后c 会递增。所以你进入了else状态,但 c 的值已经是 12。