【问题标题】:Multiple Conditions in If Statement or SplittingIf 语句或拆分中的多个条件
【发布时间】:2013-10-14 09:25:40
【问题描述】:

当我使用带有多个条件的 if 语句时,它们在编译器中是如何管理的?

A) 如果第一个语句不满足,它会忽略第二个语句吗?反之亦然?

If(time > 3.0 && hitEnabled)

B) 通常建议使用后期定义,所以我应该更喜欢在 if 语句中使用一个条件吗?

if(time > 3.0)
    if(hitEnabled)

谢谢!

【问题讨论】:

  • google 短路
  • msdn.microsoft.com/en-us/library/2a723cdk.aspx 阅读最上方的备注区。 || 也是如此。就我个人而言,我专注于使它们具有可读性以表达意图,而不是“优化”。
  • 或 mpore 准确地谷歌“短路评估”(-:

标签: c# c++ compiler-construction


【解决方案1】:
if(time > 3.0 && hitEnabled)

time > 3.0 为假时,将不会评估上述语句中的hitEnabled

这称为短路。

即使time > 3.0 为假,以下语句也会计算hitEnabled,但当两个操作数都是true 时返回真。

if(time > 3.0 & hitEnabled)//note bitwise &

if(time > 3.0)
    if(hitEnabled)

当您需要多次检查第一个条件等时,嵌套 if 语句很有帮助。

if(time > 3.0 && hitEnabled)
{
//DoSomething1
}
if(time > 3.0 && flag)
{
//DoSomething2
}

这可以用嵌套的 if 语句重写,如下所示

if(time > 3.0)
{
    if(hitEnabled)
    {
    //DoSomething1
    }
    if(flag)
    {
    //DoSomething2
    }
}

在这种情况下,我更喜欢嵌套 if 语句以避免不必要的检查

【讨论】:

  • 总是计算第二个操作数这一事实并不是&&& 之间的唯一区别。隐式转换的工作方式也不同,如果涉及隐式转换,即使ab 都为 true,您最终可能会得到 a & b false。
  • @JamesKanze 我无法关注你。你在说EvilBool的事吗?
  • 没有。我只是指出&|not 布尔运算符,并且不要对bool 进行操作。表达式中的任何bool 都将隐式转换为int。如果两个运算符实际上都是bool(并且已正确初始化),则应该没有问题,否则......if somebool & isalpha( ch ) 可能会评估为假,即使两个条件都为真。
  • @JamesKanze bool 不能隐式转换为 int。我刚刚测试了
  • §4.6/6:“bool 类型的纯右值可以转换为 int 类型的纯右值,false 变为 0,true 变为 1。”
【解决方案2】:

&& 的情况下,如果第一个条件为假,则永远不会评估第二个条件并且总体结果为假。在|| 的情况下,如果第一个条件为真,则不评估第二个条件并且总体结果为真。正如 Rob 所指出的,它被称为短路评估。

当我们想要评估 if 语句的第二个操作数时,这很有用,只有当第一个操作数返回 true 时。例如,我们可能想在使用变量之前检查它的有效性。

if(ptr != NULL && *ptr > x)

在这种情况下,ptr 的值将仅在 x 不是 NULL 时与 x 进行检查。

【讨论】:

  • 它被称为短路评估给它一个正确的名字@Kunal。 (-:
  • @RobWells 我将在答案中添加。谢谢。
【解决方案3】:

A) 如果第一个条件为假,它不会检查 hitEnabled,如果你想这样做,你必须使用短路 AND (&) 如下所示。即使第一个条件为 False,它也会检查第二个条件。

If(time > 3.0 & hitEnabled)

B) 这很大程度上取决于您希望从应用程序中得到什么,而不是硬件性能。如果您想在任何情况下检查这两个条件,B 选项 非常好,但如果您确定 time > 3.0 为 false 并且您不想检查第二个,则 A 选项 在我看来更可取。正如我之前所说,这在很大程度上取决于您程序的逻辑,因此您无法根据一行代码得到正确的答案。

如果您问在没有逻辑背景的情况下有什么更好的写作方式,这取决于您。如果您遵循代码约定,这两种变体都易于阅读。

【讨论】:

  • 使用短路与时,两个语句都被检查,但如果其中一个为假,则整个语句为假,那么使用短路与有什么意义?
  • @user1767754 这取决于您的条件逻辑。有时您想使用 AND 运算符检查所有条件是否为 true 或 false,然后使用短路 AND,但如果第一个条件为 false 并且您 不关心其他条件(无论是真是假),所以没有任何意义使用&你可以使用普通的&&。
【解决方案4】:

一旦确定为真或假,表达式的计算就会停止。

这允许像 if (x != null && x.property ... 这样的表达式,因为如果 x 为 null 等,则不会计算 x.property。

【讨论】:

    【解决方案5】:
            String someString = null;
    
            if (someString != null && someString[4].Equals('a'))
            {
                //// not called
            }
    
            if (someString != null || someString[4].Equals('a'))
            {
                //// exception
            }
    
            Console.ReadLine();
    

    【讨论】:

      【解决方案6】:

      第一种情况:

      If(time > 3.0 && hitEnabled)
      

      如果time > 3.0 为假,则永远不会检查hitEnabled。它总是从左到右开始检查条件。

      如果您想确保检查所有条件,您应该使用||(逻辑OR)而不是&&(逻辑AND),例如:

      If(time > 3.0 || hitEnabled)
      

      这个:

      if(time > 3.0 && hitEnabled)
      

      等于

      if(time > 3.0)
      if(hitEnabled)
      

      【讨论】:

      • 我知道,OR 运算符是一个选项,我的问题不是关于运算符,而是编译器如何处理 If 条件中的 && 运算符
      • 也许我说得不够清楚,但它也包含在我的回答中:'如果时间 > 3.0 为假,则永远不会检查 hitEnabled。它总是从左到右开始检查条件。'
      【解决方案7】:

      如果第一个条件被违反,它不会检查第二个条件,它只是忽略。 如果您想放置任何代码,最好将其嵌套。

      【讨论】:

        猜你喜欢
        • 2014-08-13
        • 2015-01-20
        • 2013-12-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-09-25
        相关资源
        最近更新 更多