【问题标题】:Determining the print of C确定 C 的打印
【发布时间】:2017-07-01 15:56:12
【问题描述】:

我正在审查 C 上的材料。我不确定为什么答案是 12 和 32。在第一个 printf() 中,我认为 %d = 2 (i)、%d = 2 (j), \n = 换行。谁能解释一下?

#include <stdio.h>
int main(void) {
    int i,j;

    i=2 && (j=2);
    printf("%d%d\n",i,j);

    (i=3) || (j=3);
    printf("%d%d\n",i,j);
}

【问题讨论】:

  • 这段代码是谁写的?
  • 这是一个复习题
  • i=2&amp;&amp;(j=2) 是如何解析的?您可以在 C 标准中查找运算符的优先级。
  • 只需在评论上标记“失败”即可:(

标签: c


【解决方案1】:

对于第一个表达式,i=2 &amp;&amp; (j=2); 被隐式评估为 i = (2 &amp;&amp; (j = 2));,因为赋值运算符 = 的优先级低于逻辑运算符。在第一个条件中,2 的真值为true,逻辑与&amp;&amp; 导致对所有条件求值,这意味着j = 2 也被求值,将2 分配给j 并返回2,结果为@987654328 @。所以现在要计算的实际表达式是i = 2 &amp;&amp; 2;,即true,或者用C 的术语来说,1。所以,i 被赋值为1,第一个输出是12

对于第二个表达式(i=3) || (j=3);,使用逻辑或||,并且短路确保如果第一个条件计算为true,则整个表达式为true,因此不计算第二个条件.所以在 i = 3 被计算之后,i 被赋值为 3 并且整个表达式为真,所以 j = 3 没有被计算。所以第二个输出是32

【讨论】:

    【解决方案2】:

    根据优先级,第一个表达式计算为

      i = (2 && (j=2)); 
    

    所以 i=1(真)和 j=2。这就是为什么第一个输出是 12。

    第二个表达式是两个赋值的逻辑或。

    (i=3) || (j=3); 
    

    但由于左侧的第一个评估是“真”(i=3),第二个评估没有完成。这就是为什么 j 的值仍然是 2 而第二个输出是 32(不是 33)。

    【讨论】:

      【解决方案3】:

      打印 12 而不是 22 的原因是因为 i 被分配了 2 &amp;&amp; (j=2) 的值。首先将j 分配给2。然后(j=2) 返回2。之后2 &amp;&amp; 2 被评估为true,并返回true。这是因为 && 检查双方是否为真,2 被解释为真。由于双方都为真,所以它返回真,即 1。

      如果左侧被评估为真,|| 不会评估右侧。原因是没有必要。如果至少其中一个运算符的计算结果为真,并且 i=3 计算结果为 3,则它应该计算为真,这被解释为真。这就是打印 32 而不是 33 的原因。

      如果左操作数为真则不计算右操作数的特性可用于执行此操作:

      foo() || printf("foo() returned false\n");
      

      与 && 类似,但如果 left 计算结果为 false,则此运算符不计算右操作数。

      foo() && printf("foo() returned true\n");
      

      请注意,我并不是建议应该使用这些技巧。我只是以它们为例说明 ||并且 && 可能会根据左侧的值跳过对右侧操作数的评估。

      【讨论】:

      • 我可以理解为什么现在是 32,但第一次打印不应该是 22 而不是 12?
      • @jan86 我现在添加了一个解释。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-17
      • 1970-01-01
      • 2012-02-13
      • 1970-01-01
      相关资源
      最近更新 更多