据我所知,如果一个“如果”块不提供大括号则只有1陈述,认为里面。 例如
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演示: 无括号和用大括号 。
该行为是不是实际上是不同的,这是完全一致的:整个内if
块-包括else if
-被认为是一个块。
这是在分析经典模糊性,被称为“dangling- else
问题” :有些时候语法在正常BNF减记解析这两种有效方法:
任一尾随else
为外块,或内块的一部分。
大多数语言解析由(任意)决定该块解析器贪婪地匹配的模糊性-即else
[ if
]被分配到最接近if
。
因为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";
}
}
}
你可以明确地把你想让他们的括号解决问题。
它不应该打印出任何东西。 如果/否则,如果是属于第一,如果一个块是等同于此,由于第二:
if(false) {
if(false) // nested - if
cout << "false false\n";
else if(true)
cout << "true\n";
}
这是从C解析器viepoint很自然的。
解析器,在解析if语句,解析条件表达式,然后再解析条件后的第一个语句,然后寻找其他关键字,如果别的礼物,解析第二(替代)语句。
然而,第一条语句是一个if语句,所以解析器调用“如果解析器”递归(用于测试其他关键字之前!)。 这个递归调用解析内if-else语句完全(包括人 ),并且移动标记位置“过去的结束”整个代码片段。
实施替代行为的任何企图应包括“外”与“内”如果的解析器之间的一些额外的通信:外解析器应该告知“内部”不贪(即不要吃else语句)。 这将增加额外的复杂语言的语法。
else
语句总是连接到最近的if
。 如果没有嵌套分支if
本身不构成有意义的语句,所以解析器继续。