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 braces和with braces]。
答案 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
本身不会形成有意义的语句,所以解析器继续。