在C中意外地使用printf()

时间:2013-11-01 10:34:42

标签: c printf

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

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

3 个答案:

答案 0 :(得分:2)

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

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

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

答案 1 :(得分:1)

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

直接来自维基百科:

  

在函数调用中输入函数之前。顺序在哪   未指定参数的计算,但此序列点   表示在功能之前所有副作用都已完成   进入了。

此处有更多信息:http://en.wikipedia.org/wiki/Sequence_point

答案 2 :(得分:0)

这两个答案都犯了同样的错误。它明确的UB而不仅仅是未指明的行为。

您所经历的是Undefined behavior。请阅读序列点。逗号是函数调用中的分隔符,而不是运算符。

序列点是尘埃落定的时间点,到目前为止所见的所有副作用都保证完整。 C标准中列出的序列点是:

  

在完整表达式的评估结束时(完整的   expression是一个表达式语句,或任何其他表达式   不是任何更大表达式中的子表达式);       在||,&amp;&amp;,?:和逗号运算符;和       在函数调用(在评估所有参数之后,以及在实际调用之前)。

标准规定

  

在前一个和下一个序列点之间,一个对象应该具有它   通过表达式的评估,最多修改一次存储值。   此外,只能访问先前值以确定   值存储。

首先评估哪些"%d %d \n",此++i或此++i(第二个) - 考虑一下。这将是未指明的行为:

void f(int x)
{
    printf("%d ",x);
}
int main()
{
    int i=0;
    f(i++) ;
}

来自wiki:

  

在函数调用中输入函数之前。顺序在哪   未指定参数的计算,但此序列点   表示在功能之前所有副作用都已完成   进入。在表达式f(i ++)+ g(j ++)+ h(k ++)中,调用f   使用i的原始值的参数,但是i递增   在进入f的身体之前。同样,之前更新了j和k   分别输入g和h。但是,没有具体说明   执行f(),g(),h(),也不执行i,j,k的顺序   递增。 f体中的变量j和k可能有也可能没有   已经增加了。注意,函数调用f(a,b,c)不是a   使用逗号运算符和a,b和c的评估顺序   没有具体说明。