为什么在以下代码中printf函数显示所需的输出?

时间:2019-06-17 08:14:28

标签: c++ printf calling-convention

#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
    int a=1;
    printf("%d\t%d\t%d\n",a,++a,a++);
    return 0;
}

为什么代码的输出为3 3 1。有人向我解释这种输出是如何发生的?

2 个答案:

答案 0 :(得分:2)

好像您的编译器从右到左读取参数

printf("%d\t%d\t%d\n",a,++a,a++); // a = 1

a ++返回a并将其递增1

printf("%d\t%d\t%d\n",a,++a, 1); // a = 2

++ a将a加1并返回结果

printf("%d\t%d\t%d\n",a, 3, 1); // a = 3

a只是一个

printf("%d\t%d\t%d\n", 3, 3, 1); // a = 3

但是AFAIK有点像UB,因为c ++标准不规定读取参数的顺序,所以我不敢打赌,在不同的编译器上也一样

编辑:对于C ++ 17,它不再是UB,而是未指定。您仍然应该避免使用它

答案 1 :(得分:0)

根据评估顺序,这是未定义的行为。 reference(请参阅未定义行为一章)

输出为:

  

3 3 1

因为它的评估如下:

  

a ++
  使用a(1)且a变为2
  ++ a
  a变成3并使用a(3)
  使用a(3)

重要的是要知道a++是后递增的,而++a是前递增的。 后递增表示:使用该值,然后增加该值。 预先递增意味着:递增值并使用递增的值。

边注:C ++ 17将其从未定义的行为更改为未指定的行为,但在以前的版本中,它仍然是未定义的行为。