【问题标题】:What will be the value of j after this C code is executed?这段 C 代码执行后 j 的值是多少?
【发布时间】:2017-05-16 15:18:12
【问题描述】:

为什么下面的代码执行后j的值为零?

int main()
{
    int i = 0, j = 0;

    if (i && (j = i + 10))
    //do something ;
}

如果我将逻辑与替换为按位与,为什么值10

另外,为什么在执行下面的代码后 j 的值又为零?

    int i = 10, j = 0;

    if (i || (j = i + 10))

        //do something

        ;

【问题讨论】:

  • 因为逻辑运算是短路的。按位不是。
  • 您还能期待什么?为什么?
  • 最后一种情况,如果是||运算符,因为 i 不是 1,它不应该短路并继续进行。然后 j 应该变成 10。这就是我所期望的@Olaf
  • @RajeshSh 在 C 中,All 非零整数为真,而不仅仅是1。零是假的。因此,true || something 的计算结果为 true,而 something 未计算。

标签: c bitwise-operators logical-operators


【解决方案1】:

因为逻辑和 (&&) 短路。考虑:

a() && b() && c();

如果a()返回false,根据and运算的定义,整个结果都是false,所以不需要计算b()c()(事实上,C不会执行b()c())。在您的情况下,&& 在注意到 i == 0(在 C 中是错误的)后放弃了。

同样,逻辑或 (||) 在第一个计算结果为真的表达式上短路。考虑:

a() || b() || c()

如果a() 仍然返回false(如前面的示例),但b() 返回true,则不会计算c(),因为在计算b() 后,整个逻辑运算的值是已知的。

按位与 (&) 与逻辑与完全不同。您使用逻辑和控制流(决定运行什么代码);您使用按位和计算位的 操作。按位运算不像逻辑运算,它们更像 算术 运算 - 它们的行为类似于例如+*

【讨论】:

  • b() 不仅没有必要,而且在很多情况下是严格禁止的。考虑像 if (x != NULL && strlen(x)>2) 这样的东西 - 正确的部分在评估时可能会崩溃。
  • 从了解操作价值的角度来看,我的意思是不必要的。 C 确实被指定为始终在逻辑操作上短路,以便它可以支持您的示例中的代码。
  • @ErichKitzmueller - but in many cases strictly forbidden...嗯,不止这些。这是始终严格禁止的。
  • @4386427 你当然是对的。我想指出在许多情况下会发生的致命后果,但规范是明确的
【解决方案2】:

&& 短路考虑如下:

int main()
{
   int i = 0, j = 0;

   if (i){
      if(j = i + 10)){
          //do something ;
      }
   }
}

这与您的示例等效。如果您按照您提到的那样替换订单(j = i + 10) && i,则等效如下:

int main()
{
   int i = 0, j = 0;

   if (j = i + 10){
      if(i)){
          //do something ;
      }
   }
}

您可以亲自了解为什么j 的值在第一个代码块中为零,而在第二个代码块中为零。

【讨论】:

    【解决方案3】:

    因为i && (j = i + 10) 表示短路行为的逻辑与运算。不会评估 (j=i + 10),因为 i 是逻辑 0(假)。每个表达式都必须计算为标量逻辑结果。

    【讨论】:

      【解决方案4】:

      j = i + 10j == i + 10 不同。前者为j 赋值(在本例中为10,因为i0),后者将ji + 10 进行比较。

      当您拥有&& 时,j = i + 10 将被忽略,因为它已经知道 i 为 0,因此第一部分为 false。当您将其设为& 时,它会查看& 运算符的两侧并将值分配给j。这可能是您想要做的事情,也可能不是 - 目前尚不清楚您要对代码做什么。

      【讨论】:

        【解决方案5】:

        我更喜欢这样看:

        if (A && B)
        {
            DoSomething();
        }
        

        相同
        if (A)
        {
            if (B)  // So B is only evaluated when A results in TRUE
            {
                DoSomething();
            }
        }
        

        if (A || B)
        {
            DoSomething();
        }
        

        相同
        if (A)
        {
             DoSomething();
        }
        else if (B)  // So B is only evaluated when A results in FALSE
        {
            DoSomething();
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-08-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-03-27
          • 1970-01-01
          • 2023-02-26
          相关资源
          最近更新 更多