2014-03-04 121 views
0

我遇到以下代码片段。C条件声明

int main() 
{ 
    int i=1,j=2; 
    int a=i--?printf("%d",i):j--; 
    printf(" %d %d %d",i,j, a); 
    return 0; 
} 

的输出是0 0 2 1

我明白输出的其余部分除了第0

请帮助。

谢谢。

+0

你的问题是什么? – Linuxios

+0

由'i - '由1改为0。 – Dan

+0

哦,明白了。谢谢:) – psyc0der

回答

2

第一个0i的值,它初始化为1,然后在第二行中递减。

更明确地说:

i = 1 
(i--) - evaluates as True, then sets i to 0 
printf("%d ", i) = prints '0' 
j-- - skipped 
printf("%d %d %d", i, j, a) 
print i: 0 
print j: 2 (unchanged) 
print a: return value of first `printf` : character count (1) 

由于@tristopia在评论中指出,也有在这里打球两个密切相关的概念:

  1. 后固定运营商:就是在使用的值在增量发生之前的表达式是的值...
  2. 序列点:代码中“先前评估的所有副作用将被执行”的点 - 她的话说,“在我们通过这一点之前,所有需要发生的事情都会发生”。例如,在传递序列点时,后缀增加的任何变量都会保证递增(并存储)。

这里的关键是三元运算符的?是这样一个顺序点 - 因此你确信i将你到printf语句之前已经递减。

对比这与像代码:

i = 1; 
a = 5 * i++ + (i = 2 * i--); 

这会导致不确定的行为 - 没有什么C标准,它可以告诉你确切的ai值将是什么上面了。 i++的值应该什么时候存回i?减量操作之前?我们将结果分配给i的事实如何?它是在其他“隐性商店”运营之前或之后发生的吗?大多数编译器会在遇到这样的问题时提醒你 - 如果你有特定的操作顺序,你应该通过重写代码来“强制顺序点”。

+0

我明白我会减少。但是因为他们使用了一个后缀操作符,所以我很困惑。所以如果我是对的,评估语句,然后我递减,然后打印。? – psyc0der

+0

即使那段代码很丑,我也没有看到任何导致未定义行为的东西。 –

+0

@MichaelWalz - 你说得对,我仔细一看。相应更新。 – Floris

1

那么你打电话printf()两次。条件运算符中的第一个输出值为i(0)。当您创建变量a时,它的默认值为0,i在用i--递减后变为0,因此条件已通过。

然后你有你的第二个printf(),再次打印i以及其他2个值。

2

在条件检查完成之前,i的值不会减少(由于后缀减少)。测试评估为true,因为我是1,导致printf得到执行。但正如我对i的测试结束,它会减少,这是printf在屏幕上打印的东西。