“if”没有花括号的块会使后续的“else if”嵌套

时间:2012-07-31 06:48:35

标签: c++ c if-statement nested-if

AFAIK,如果" if"大括号不提供块,然后在其中只考虑1个语句。 e.g。

if(..)
  statement_1;
  statement_2;

无论选项卡如何,statement_1块中都只考虑if

以下代码与之相配:

int main ()
{
  if(false)  // outer - if
    if(false)  // nested - if
      cout << "false false\n";
  else if(true)
    cout << "true\n";
}

以上代码不打印任何内容。它应该打印"true" 它显示为else if自动嵌套在外部 if块中。 g++ -Wall发出警告,但这不是问题。一旦你放上花括号,一切都按预期正常。

为什么会出现这种不同的行为? [GCC演示:without braceswith braces]。

5 个答案:

答案 0 :(得分:49)

行为实际上并没有区别,它完全一致:整个内部if块 - 包括else if - 被视为一个块。

这是解析中的经典歧义,称为“dangling-else problem”:当语法在普通BNF中写下时,有两种有效的解析方法:

尾随else是外部块或内部块的一部分。

大多数语言通过(任意)决定解析器贪婪地匹配块来解决模糊性 - 即else [if]被分配给最接近的if

答案 1 :(得分:6)

因为else实际上与内部 if分组,而不是外部分组。它实际上被解析为

int main ()
{
  if(false)  // outer - if (never gets executed)
  { 
    if(false)  // nested - if
    {
        cout << "false false\n";
    } else if(true) {
        cout << "true\n";
    }
  }
}

您可以通过明确地将大括号放在您想要的位置来解决问题。

答案 2 :(得分:2)

它不应该打印任何东西。它等同于此,因为第二个if / else if是属于第一个if的一个块:

  if(false) {
    if(false)  // nested - if
      cout << "false false\n";
    else if(true)
      cout << "true\n";
  } 

答案 3 :(得分:2)

从C解析器角度来看很自然。

解析器在解析if语句时首先解析条件表达式,然后在条件之后解析第一个语句,然后查找 else 关键字,如果 else 礼物,解析第二(替代)陈述。

但是,第一个语句也是if语句,因此解析器递归调用“if-parser”(在测试 else 关键字之前!)。这个递归调用完全解析内部的if-else语句(包括 else ),并将标记位置“移到整个代码片段的末尾”。

任何实现替代行为的尝试都应该涉及“外部”和“内部”if-parser之间的一些额外的通信:外部解析器应该告知“内部”不要贪婪(即不要吃 else < / em>声明)。这会增加语言语法的复杂性。

答案 4 :(得分:1)

else语句始终附加到最近的if。没有分支嵌套if本身不会形成有意义的语句,所以解析器继续。