2017-08-25 96 views
-4
#include<stdio.h> 
int main(){ 
    int i=1,j=6,k=8; 
    printf("%d %d %d %d %d %d %d %d",i,k,j,j++,++i,j,i,i); 
} 

我无法理解输出。如果有人能解释我,这将会很有帮助。 输出:2 8 7 6 2 7 2 2在一个函数中如何评估多个参数C

+0

那么,printf参数在被传递给printf之前被评估,但是C标准没有指定如何以及以何种顺序完成,所以结果基本上是未定义的。这没有实际用途 - 只是不这样做。 – SBS

+0

欢迎堆栈溢出。请注意,在这里说'感谢'的首选方式是通过提高投票的好问题和有用的答案(一旦你有足够的声望这样做),并接受对你问的任何问题最有用的答案(这也给你对声望的小小提升)。请参阅[关于]页面以及[如何在这里提问?](http://stackoverflow.com/help/how-to-ask)和[当某人回答我的问题时我该怎么办?](http ://stackoverflow.com/help/someone-answers)即使问题已关闭,也值得接受一个很好的答案。 –

+0

由于评论长度有限,我已将该陈述改为 printf(“%d%d%d%d”,i,++ i,i ++,i);其中i = 1 在评估过程中,首先将所有值从右边开始放入堆栈。如果变量具有任何后/前增量,则会评估并存储该值。否则,它将作为变量存储在堆栈中并获取var的最终值。 最右边的我 - 我进入堆栈, for i ++ - 1,因为它的post inc将我更新为2. for ++ i - 3,pre inc和更新我为3 因为我在堆栈中。 为var作为我在堆栈中取我的最终价值为3. 最终的输出将是3 3 1 3 – Dinesh

回答

3

行为是不确定。


参数可以按任意顺序评估。

C11§6.5.2.2-p(10):在函数指示符和实际参数的评估之后,但在实际调用之前有一个序列点。在调用函数(包括其它函数调用)每个评估不另外之前或调用的函数体的执行不定相对于被调用函数的执行测序后明确测序。 94)

这是不确定的行为,同时读取和表达式,其评价顺序是不改变的对象。

C11§6.5-P(2):如果一个标量对象上的副作用是相对于同一标量对象在任一个不同的副作用,或使用相同的标量对象的值的值计算未测序,行为是不确定的。如果有一个表达式的子表达式的多个可允许的排序,该行为是未定义如果在任何排序中发生这样的未测序的副作用。 84)

0

事实证明,这里的答案是没有答案。在一个表达式中,通常没有规则说明表达式的哪些部分会被第一,第二,第三等评估。

对于您的情况,调用printf(包括其所有参数)是一个表达式。但是没有规则说明printf的哪个参数得到第一,第二,第三等的评估。因此,由于一个参数是i而另一个参数是++i,因此无法知道普通i的原始值是否为i,或者修改者为++i

严格地说,这里的行为是不确定的

这对你有三层含义:

  1. 你不需要记住这可以解释做什么类似的代码printf("%d %d\n", i, ++i)规则。
  2. 你从来没有花时间去了解做什么类似的代码printf("%d %d\n", i, ++i)
  3. 你最好永远不会写代码一样printf("%d %d\n", i, ++i)