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