0

我无法理解以下代码的输出如何是“-3”?

#include <stdio.h>
void main()
{
    int a = -5;
    int k = (a++, ++a);
    printf("%d\n", k);
}

int k = (a++, ++a);在 c 或 c++ 中这个语句背后的概念是什么 ?

4

4 回答 4

5

它之所以起作用,是因为,创建了一个序列点的运算符。

§5.19.1(逗号运算符)

逗号运算符从左到右分组。一对用逗号分隔的表达式从左到右求值;左边的表达式是丢弃的值表达式(第 5 条)。与左表达式关联的每个值计算和副作用都在与右表达式关联的每个值计算和副作用之前排序。结果的类型和值是右操作数的类型和值;结果与其右操作数属于相同的值类别,并且如果其右操作数是泛左值和位域,则结果是位域。如果右操作数的值是临时的(12.2),则结果是临时的。

所以:

  1. a被初始化为-5
  2. 然后a++执行,修改a-4.
  3. 然后++a执行,修改a为,-3然后返回-3k
于 2015-06-29T12:15:32.250 回答
1

这不是未定义的行为

在您的代码中,

 int k = (a++, ++a);

正在使用“逗号运算符”。在a被初始化为之后-5,所做的基本上是,

  • 执行a++,丢弃结果++post-的副作用a是现在-4
  • 遭遇,,序列点。
  • 执行++a,返回结果a现在是-3(pre- ++),它被分配给k.

参考:来自C11标准,章节6.5.17

逗号运算符的左操作数被评估为 void 表达式;在它的求值和右操作数的求值之间有一个序列点。然后对右操作数求值;结果有它的类型和值。

于 2015-06-29T12:15:46.707 回答
1

这在 C 和 C++ 中都得到了很好的定义。

用逗号分隔的表达式从左到右计算。

整个表达式的值将是第二个表达式的值。

因此,要分解(a++, ++a)a++首先评估(然后a是-4) ,然后丢弃结果(-5) ,然后++a评估。该值 (-3) 分配给k

于 2015-06-29T12:17:45.783 回答
1

这里使用了一个带有逗号运算符的表达式作为初始值设定项

int k = (a++, ++a);

根据 C 标准(同样适用于 C++ )(6.5.17 逗号运算符):

2 逗号运算符的左操作数被评估为 void 表达式;在它的求值和右操作数的求值之间有一个序列点。然后对右操作数求值;结果有它的类型和值

最初变量 a 用 -5 初始化

int a = -5;

因此,在对逗号运算符的第一个表达式求值后,由于“在其求值与右操作数的求值之间存在一个序列点”这一事实, a 将等于 -4 (a++)。使用逗号运算符的整个表达式的结果将是对正确表达式求值后的值++a。它的值为-3

因此变量 k 将被初始化为 -3。相同的值将具有变量 a。

于 2015-06-29T12:22:18.753 回答