0
#include<stdio.h>
int main()
{
    int i=2;
    printf("%d %d \n",++i,++i);
}

上面的代码给出了一个输出4 4。任何人都可以帮助解释输出吗?

4

3 回答 3

2

++i 是前缀增量。Printf 应该在打印它们之前首先评估它的参数(尽管不能保证按什么顺序,严格来说,未定义 - 请参阅关于未定义行为的 Wiki 条目:http ://en.wikipedia.org/wiki/Undefined_behavior )。

前缀增量称为“增量和获取”,即它首先增加值,然后将其提供给调用者。

在您的情况下,i首先增加了两次,然后才将输出格式化并发送到控制台。

于 2013-11-01T10:39:11.593 回答
1

它与序列点有关,并且可能导致未定义的行为。

直接来自维基百科:

在函数调用中输入函数之前。未指定评估参数的顺序,但此序列点意味着在输入函数之前,它们的所有副作用都已完成。

更多信息在这里:http ://en.wikipedia.org/wiki/Sequence_point

于 2013-11-01T10:38:50.547 回答
0

两个答案都犯了同样的错误。其明确的 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 的评估顺序。

于 2013-11-01T10:58:08.320 回答