3

这是我的简单代码...

#include<stdio.h>
int main()
{
int i=5;
printf("%d %d %d %d %d ",i++,i--,++i,--i,i);
return 0;
}

在 gcc 上,它的输出为 '4 5 5 5 5'

但在 TC 上,它的输出为 '4 5 5 4 5'

我知道在 printf 语句中,如果它是单个表达式,则评估将是从左到右,但在正常语句中,它将是从左到右。

但是如果 printf 包含多个表达式,则评估将在堆栈上,元素将从左到右推入堆栈但从右到左弹出,这证明了 TC 输出

请纠正我我哪里错了???

4

5 回答 5

8

C 没有指定应该以哪个顺序函数参数进行评估,因此它是未定义的,编译器可以按照他们的选择来执行,包括任意和随机。Bjarne Stroustrup 在“C++ 编程语言”第 3 版第 6.2.2 节中明确说明了这一点

他还给出了一个理由:

Better code can be generated in the absence of restrictions on expression evaluation order
于 2011-12-30T16:55:41.453 回答
3

我认为没有指定评估函数调用的参数的顺序。正如维基百科在这篇关于序列点的文章中所说:

未指定评估参数的顺序

于 2011-12-30T16:56:38.957 回答
3

i在前一个序列点和下一个序列点之间多次修改一个对象(在此代码中)是 C 中未定义的行为。这里序列点出现在所有参数都被评估后的函数调用处。

于 2011-12-30T17:06:42.657 回答
0

此时的两个答案调用了函数参数评估的不确定性。正确的答案是您的程序未定义,因为对未由序列点分隔的同一变量的副作用。

实际上,函数参数的评估顺序是未指定的。这意味着在语句中f(g(), h());,要么g()在之前调用,要么在h()之后调用。

但是,未排序的副作用(如在您的程序中)会调用未定义的行为,任何事情都可能发生。

于 2011-12-30T17:07:24.847 回答
0

碰到一个老话题,但我刚刚发现 gcc 和 Visual Studio 编译器如何在一个语句中对同一个变量进行多次更改,所以想在这里分享它。

The compiler as defined here starts to implement stack method on the arguments being passed in printf which is 'i'. It follows these rules:-

1) Now it executes the pre-increments first therefore starting from right normal i then --i and then ++i are executed and the value of i after ++i is 5 so it implements these values (pops) so output is _ _ 5 5 5

2) Then it continues right to left and executes post increments therefore, i-- and then i++ so the value of i in the end is back to 5 but due to i-- it becomes 4 but shows 5 due to it being a post increment therefore the final output is 4 5 5 5 5 and the final value of i is 5

Hope I am able to clear your doubts.

TC doesn't follow this so it adheres to our human logic.

于 2014-03-25T09:53:49.700 回答