考虑以下代码:
void res(int a,int n)
{
printf("%d %d, ",a,n);
}
void main(void)
{
int i;
for(i=0;i<5;i++)
res(i++,i);
//prints 0 1, 2 3, 4 5
for(i=0;i<5;i++)
res(i,i++);
//prints 1 0, 3 2, 5 4
}
查看输出,似乎每次都不会从右到左评估参数。到底发生了什么?
答案 0 :(得分:7)
未指定函数调用中参数的评估顺序。编译器可以按照它可能决定的顺序对它们进行评估。
来自C99标准6.5.2.2/10“函数调用/语义”:
函数指示符的评估顺序,实际参数和 实际参数中的子表达式未指定,但有一个序列点 在实际通话之前。
如果您需要确保特定订购,使用临时工具是常用的解决方法:
int i;
for(i=0;i<5;i++) {
int tmp = i;
int tmp2 = i++;
res(tmp2,tmp);
}
更重要的是(因为它导致未定义的行为,而不仅仅是未指定的行为)是您通常不能在表达式中多次使用操作数来增量/减量运算符。那是因为:
在前一个和下一个序列点之间,对象的存储值最多只能通过表达式的计算修改一次。此外,先前的值应该只读以确定要存储的值。 (6.5 / 2“表达”)
答案 1 :(得分:3)