#include<stdio.h>
int main()
{
int i=2;
printf("%d %d \n",++i,++i);
}
上面的代码给出了一个输出4 4
。任何人都可以帮助解释输出吗?
++i 是前缀增量。Printf 应该在打印它们之前首先评估它的参数(尽管不能保证按什么顺序,严格来说,未定义 - 请参阅关于未定义行为的 Wiki 条目:http ://en.wikipedia.org/wiki/Undefined_behavior )。
前缀增量称为“增量和获取”,即它首先增加值,然后将其提供给调用者。
在您的情况下,i
首先增加了两次,然后才将输出格式化并发送到控制台。
它与序列点有关,并且可能导致未定义的行为。
直接来自维基百科:
在函数调用中输入函数之前。未指定评估参数的顺序,但此序列点意味着在输入函数之前,它们的所有副作用都已完成。
两个答案都犯了同样的错误。其明确的 UB 而不仅仅是未指定的行为。
你所经历的是未定义的行为。请阅读有关序列点的信息。逗号是函数调用中的分隔符而不是运算符。
序列点是尘埃落定的时间点,到目前为止已经看到的所有副作用都保证是完整的。C标准中列出的序列点是:
在完整表达式的评估结束时(完整表达式是表达式语句,或任何其他不是任何更大表达式中的子表达式的表达式);在 ||、&&、?: 和逗号运算符处;并在函数调用中(在评估所有参数之后,就在实际调用之前)。
该标准指出
在前一个和下一个序列点之间,对象的存储值最多只能通过表达式的评估修改一次。此外,只能访问先验值以确定要存储的值。
首先评估的是 this "%d %d \n"
, this++i
或 this ++i
(第二个) - 考虑一下。这将是未指定的行为:
void f(int x)
{
printf("%d ",x);
}
int main()
{
int i=0;
f(i++) ;
}
来自维基:
在函数调用中输入函数之前。未指定评估参数的顺序,但此序列点意味着在输入函数之前,它们的所有副作用都已完成。在表达式 f(i++) + g(j++) + h(k++) 中,使用 i 的原始值的参数调用 f,但在进入 f 的主体之前 i 会增加。类似地,j 和 k 在分别输入 g 和 h 之前被更新。但是,没有指定 f()、g()、h() 的执行顺序,也没有指定 i、j、k 的递增顺序。f 主体中的变量 j 和 k 可能已经增加,也可能没有增加。请注意,函数调用 f(a,b,c) 不使用逗号运算符,并且未指定 a、b 和 c 的评估顺序。