可能重复:
Could anyone explain these undefined behaviors (i = i++ + ++i , i = i++, etc…)
我无法理解此程序的输出(使用gcc
)。
main()
{
int a=10;
printf("%d %d %d\n",++a, a++,a);
}
输出:
12 10 12
另外,请解释printf()
的论据评估顺序。
答案 0 :(得分:9)
编译器将按照当时的感觉顺序评估printf
的参数。它可能是一个优化的东西,但不能保证:它们被评估的顺序不是由标准指定的,也不是实现定义的。没有办法知道。
但是标准指定的是,是在一次操作中两次修改同一个变量是未定义的行为; ISO C ++ 03,5 [expr] / 4:
在前一个和下一个序列点之间,标量对象应通过表达式的计算最多修改一次其存储值。此外,只能访问先前值以确定要存储的值。对于完整表达式的子表达式的每个允许排序,应满足本段的要求;否则行为未定义。
printf("%d %d %d\n",++a, a++,a);
可以做很多事情;按照你的预期工作,以你永远无法理解的方式工作,崩溃,爆炸,或者如果感觉特别诙谐,向你的母亲发送讨厌的电子邮件(尽管这种结果通常出现在缓冲区超支和其他此类悲剧中)。 p>
你不应该写这样的代码。为了你的家人的缘故。
答案 1 :(得分:6)
AFAIK没有为函数调用的参数定义评估顺序,结果可能因每个编译器而异。在这个例子中,我可以猜测中间参数首先被评估,然后是第一个和第三个。
答案 2 :(得分:0)
正如haggai_e暗示的那样,参数按以下顺序评估:中,左,右。 要完全理解为什么会显示这些特定数字,您必须了解增量的工作原理。
a ++意味着“用a做某事,然后再增加它”。 ++ a表示“先增加第一个,然后使用新值执行某些操作”。
在您的特定示例中,printf首先计算++,读取10并打印它,然后将其递增到11.然后printf计算++ a,首先递增它,读取12并打印出来。最后一个变量printf求值按原样读取(12)并打印而不做任何更改。
虽然它们是按随机顺序评估的,但它们会按您提到的顺序显示。这就是为什么你得到12 10 12而不是10 12 12。