main()
{
int i=5;
printf("%d%d%d%d%d%d",i++,i--,++i,--i,i);
}
输出是45545,但我不知道它是如何工作的。有人说函数调用中的参数从左到右被压入堆栈。
答案 0 :(得分:19)
未指定函数参数的评估顺序。
来自c99标准:
6.5.2.2函数调用
10 /函数指示符的评估顺序,实际 参数和实际参数中的子表达式是 未指定,但在实际调用之前有一个序列点。
然而,这只是问题的一部分。另一件事(实际上更糟糕,因为它涉及未定义的行为)是:
6.5表达式
2 /在上一个和下一个序列点之间有一个对象 它的存储值最多只能通过评估一次修改 表达。此外,先前值应只读取 确定要存储的值。
在我们的例子中,所有参数评估仅在2个序列点之间:前一个;
和输入函数之前的点,但是在评估了所有参数之后。你最好不要写这样的代码。
C标准在某些地方相当宽松,为编译器可能做的优化留出了空间。
答案 1 :(得分:4)
传递函数参数的顺序未在标准中定义,并由编译器使用的calling convention确定。 我认为在你的情况下,使用cdecl调用约定(许多C编译器用于x86架构),函数中的参数从右到左进行评估。
答案 2 :(得分:3)
两点:
i
。答案 3 :(得分:3)
此函数调用是未定义的行为:
printf("%d%d%d%d%d%d",i++,i--,++i,--i,i);
在两个序列点之间多次修改对象是C中未定义的行为。
它也是未定义的行为,因为您有6个转换规范,但格式只有5个参数。
答案 4 :(得分:1)
printf
参数的评估顺序未指定。除其他外,它取决于您正在使用的系统的调用约定。此外,这也是一种未定义的行为,因为您在没有任何序列点的情况下多次修改i
。顺便说一句,有一个缺失的论点。