【问题标题】:How this statement works `int k = (a++, ++a);` in c or c++ [duplicate]此语句如何工作`int k =(a++,++a);`在c或c ++中[重复]
【发布时间】:2015-09-15 21:37:04
【问题描述】:

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

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

int k = (a++, ++a); 在 c 或 c++ 中的声明背后的概念是什么?

【问题讨论】:

  • @NathanOliver 你确定吗?
  • @JoachimPileborg 是的。我撤回了我的评论和投票。
  • 我将重新打开并重新关闭此问题,以删除错误添加到组合中的 UB 副本。
  • 为了进一步演示, 运算符的效果,您可以尝试使用(++a, ++a),然后使用(a++, a++)(这实际上只是前增量和后增量之间差异的另一个说明)。

标签: c++ c initialization comma comma-operator


【解决方案1】:

这不是未定义的行为

在您的代码中,

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

正在使用"comma operator"。在a被初始化为-5之后,基本上就是这样,

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

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

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

【讨论】:

    【解决方案2】:

    这里使用了一个以逗号操作符作为初始值设定项的表达式

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

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

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

    最初变量 a 用 -5 初始化

    int a = -5;
    

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

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

    【讨论】:

      【解决方案3】:

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

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

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

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

      【讨论】:

        【解决方案4】:

        因为, 运算符创建了sequence point,所以它可以工作。

        §5.19.1(逗号运算符)

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

        因此:

        1. a 被初始化为 -5
        2. 然后a++执行,并将a修改为-4.
        3. 然后++a执行,将a修改为-3,并将-3返回为k

        【讨论】:

          猜你喜欢
          • 2019-07-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-01-04
          • 1970-01-01
          相关资源
          最近更新 更多