有人可以解释以下C程序的结果吗?
#include<stdio.h>
int main()
{
int i=2;
printf("%d %d %d",i,i++,++i);
return 0;
}
输出4 3 4
如何?
答案 0 :(得分:3)
C ++标准未定义参数的评估顺序;而且,&#34;如果标量对象的副作用相对于同一标量对象的另一个副作用未被排序,则行为未定义&#34;。
因此,与同一函数调用的参数相同的标量值的后递增和预递增是未定义的。显然,在你的情况下,两个增量都是在评估第一个和最后一个参数之前完成的。
答案 1 :(得分:0)
您从i = 2
开始。由于i++
和++i
,变量i
增加了2(每个++
加1)。因此,完成后,其值为4.
语法i++
表示在递增之前使用值i
。这就是为什么中间数字(printf
来自i++
)不能是4。
它是4 3 4而不是其他的原因,例如2 2 4或2 3 3或4 3 3,与评估++
运算符的时间相比,printf
运算符的参数与1}}功能已设置。一个人应该永远不会编写这样的代码,至少不是任何人实际必须使用的软件。
答案 2 :(得分:0)
您已进入未定义行为的土地。 C不保证传递给函数的参数的计数顺序,特别是varargs函数。像这样的陈述的结果,这是一个经典的面试问题,是&#34;未知&#34; - 它可以在编译器版本,平台等之间进行更改,类似于以下问题:
int i = 1;
int a[3] = { 1, 2, 3 };
int j = a[i++] - a[++i];
什么是j?答:这取决于你的编译器,版本,平台等:你不能用来推断它的一件事就是C规范。
但是你想知道3,不是吗?那是因为你的编译器首先评估了++ i,它将i
增加到3.然后你的编译器评估i++
,后增量,实现等效于此(在C ++中,对不起) :
int operator ++ (int) { // post-increment indicated by int parameter
int i = *this;
this->operator++();
return i;
}
或其他伪代码
int tempI = i;
++i;
所以你真正写的是:
printf("%d %d %d\n", i, (j = i, ++i), ++i);
在评估传递给printf的参数结束时,i
的值为4
,但i++
返回的临时值保留为3的值。
因此:4(i)3(temp)4(i)