22

AFAIK,如果没有提供大括号“if”块,则其中仅考虑 1 个语句。例如

if(..)
  statement_1;
  statement_2;

不考虑选项卡,仅statement_1if块内考虑。

以下代码与此不符:

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 演示:不带大括号带大括号]。

4

5 回答 5

58
于 2012-07-31T06:51:14.177 回答
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";
    }
  }
}

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

于 2012-07-31T06:52:17.970 回答
2

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

  if(false) {
    if(false)  // nested - if
      cout << "false false\n";
    else if(true)
      cout << "true\n";
  } 
于 2012-07-31T06:51:30.317 回答
2

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

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

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

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

于 2012-07-31T08:03:13.283 回答
1

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

于 2012-07-31T06:56:36.533 回答