0

我已经经历了其他类似的问题,但试图了解我所面临的情况。

所以,这是我的两行 C 代码。

int i=0;
printf("%d %d %d %d %d",i++,i--,++i,--i,i);

这是我从 GCC 和 Turbo C 编译器获得的输出。

海合会

输出:

-1 0 0 0 0

涡轮增压 C

输出:

-1 0 0 -1 0

我分别用预增量运算符尝试了各种实验,两个编译器的工作方式相似,但是当我使用上述printf语句时,输出不同。

我知道 Turbo C 是古老的编译器,现在已经过时且非标准,但仍然不知道上面的代码有什么问题。

4

4 回答 4

8

这是未定义的行为,您在i没有序列点的情况下多次阅读和修改。(,函数参数列表中的 不是序列点,函数参数的求值顺序也没有定义。)

在这种情况下,编译器可以输出任何它想要的东西。不要那样做。

通过在此站点上搜索[C] undefined behavior. 这很有启发性。

于 2011-05-20T05:15:29.400 回答
1

Turbo C 正在评估printf()从变量参数列表中的最后一个参数到第一个参数的参数,并按该顺序打印(即,它填充最后一个值,然后在列表中向前移动,最后一个评估是列表中的第一个变量参数,打印到格式化字符串中的第一个整数槽)。另一方面,GCC 首先是评估具有前缀运算符的参数,连接这些结果,并将它们应用于所有前缀运算符(即,它正在应用--i并且++i最终等于0,然后将该值用于两者与这些参数关联的格式字符串中的插槽)。然后它转移到后修复运算符(首先i--,然后i++) ,最后它计算没有前缀或后缀运算符的变量 args(即 的值i,此时它只是0)。正如其他人所指出的,排序可以是任意的。

于 2011-05-20T05:17:47.213 回答
0

无法保证评估函数参数的顺序;这是未定义的行为。

这个顺序可以从一个版本到另一个版本,甚至编译到编译。

于 2011-05-20T05:15:22.613 回答
0

对于这种情况, Turbo C编译器有一个具体的解释。

虽然GCC或其他现代编译器对于此类歧义持续存在的表达式具有未定义的行为。

所以,这里是Turbo C编译器的解释。

printf()在评估时具有从右到左的关联性,但将以从左到右的正常方式打印。

最初i的值被初始化为0

从最右边的i开始,它将被0替换。

然后,倒数第二个--i将被 0-1 = -1替换。

然后中间的++i将被 -1+1 = 0替换。

然后第二个i--将被0替换,但现在 i 的值变为 -1。

然后第一个i++将被-1替换,但现在 i 的值变为 0。

最后以从左到右的方式打印为:

-1 0 0 -1 0

因此,您可以观察Turbo C编译器在此类表达式上的通常行为,而没有任何其他编译器对此类表达式的具体规则。

于 2013-09-21T16:19:57.317 回答