英文:
Association of else block with if block in C
问题
我有如下的代码片段。有人能解释一下为什么 else 块与嵌套的 if 块关联在一起吗?以下代码段的输出是 1。我执行了代码,但无法理解为什么块的执行顺序如下。
更新:这是我在一家公司以前年度面试题中找到的问题。我总是在我的 if 和 else 块周围使用括号。现在我明白为什么整个块没有执行。
谢谢大家的回答 ![]()
英文:
I have a code snippet as shown below. Can someone please explain me why the else block is getting associated with the nested if block? The output of the following snippet is 1. I executed the code but cannot understand why the blocks are getting associated in the following order.
UPDATE: This is a question I found in a company's previous year interview questions. I always use brackets around my if and else blocks. I now understand why the entire block is not getting executed.
Thank You everyone for your responses ![]()
int x=1, y=1;
if (y<0)
if (y>0) x=3;
else x=5;
printf("%d", x);
答案1
得分: 6
以下是翻译好的部分:
有了正确的缩进,它变得更清晰:
int x = 1, y = 1;
if (y < 0) // false, so it jumps directly here
if (y > 0) // |
x = 3; // |
else // |
x = 5; // |
printf("%d", x); // <------------------------------+
添加大括号使其更清晰。下面的代码与您的原始代码完全相同的含义:
int x = 1, y = 1;
if (y < 0) {
if (y > 0) {
x = 3;
} else {
x = 5;
}
}
printf("%d", x);
也就是说,if(condition) <statement> else <statement>。<statement> 可以是单个语句或{块}语句。没有大括号,只有下一个单个语句会有条件地执行。
英文:
With the proper indentation, it becomes clearer:
int x = 1, y = 1;
if (y < 0) // false, so it jumps directly here
if (y > 0) // |
x = 3; // |
else // |
x = 5; // |
printf("%d", x); // <------------------------------+
Adding braces makes it even clearer. The below has exactly the same meaning as your original code:
int x = 1, y = 1;
if (y < 0) {
if (y > 0) {
x = 3;
} else {
x = 5;
}
}
printf("%d", x);
That is, if(condition) <statement> else <statement>. The <statement> can be either a single statement or a {block} statement. Without braces, only the next single statement will be conditionally executed.
答案2
得分: 6
C和C++的正式语法未规定如何与else相关联,该选择由语法之外的规则指定。C 2018 6.8.4.1第3条规定:
else与语法允许的最近的if相关联。
C++ 2020 (draft N4849) 8.5.1 [stmt.if] 1 规定:
...在
if语句的第二种形式中(包括else的形式),如果第一个子语句也是一个if语句,那么内部的if语句必须包含一个else部分。[换句话说,else必须与内部的if相关联,然后外部的if才能有一个else]。
要查看语法未规定如何与else相关联,我们可以检查C 2018 6.8.4中的正式语法:
selection-statement:
if(expression)statement
if(expression)statementelsestatement
switch(expression)statement
根据这个语法,if(y<0) if(y>0) x=3; else x=5; 可能被解析为 if(y>0) x=3; else x=5; 是一个 statement,它是 "if ( expression ) statement else statement ",或者它可能被解析为 if(y>0) x=3; 是一个 statement,它是 if ( expression ) statement。在前一种情况下,父 if(y>0) 将具有没有 else 的 if 形式。在后一种情况下,父 if(y>0) 将具有 if … else 形式。
英文:
The formal C and C++ grammars do not specify how an else is associated. The choice is specified by a rule outside the grammar. C 2018 6.8.4.1 3 says:
> An else is associated with the lexically nearest preceding if that is allowed by the syntax.
C++ 2020 (draft N4849) 8.5.1 [stmt.if] 1 says:
> … In the second form of if statement (the one including else), if the first substatement is also an if statement then that inner if statement shall contain an else part. [In other words, an else has to be associated with the inner if before the outer if can have an else.]
To see the grammar does not specify how an else is associated, we can examine the formal grammar in C 2018 6.8.4:
> selection-statement:<br>
> if ( expression ) statement<br>
> if ( expression ) statement else statement<br>
> switch ( expression ) statement
With this grammar, if(y<0) if(y>0) x=3; else x=5; may be parsed as if(y>0) x=3; else x=5; being one statement that is “if ( expression ) statement else statement”, or it may be parsed with if(y>0) x=3; being one statement that is if ( expression ) statement. In the former case, the parent if(y>0) would have the if form without an else. In the latter case, the parent if(y>0) would have the if … else form.
答案3
得分: 3
以下是已翻译的内容:
if ( expression ) statement
if ( expression ) statement else statement
如您所见,else 部分不能作为独立的语句存在,必须与 if 部分一起。
因此,根据定义,这个 if 语句:
if(y<0) ...
可以被重写为:
if(y<0) statement;
statement 可以是任何语句,包括另一个 if 语句:
if(y<0) if(y>0) x=3; else x=5;
也就是说,else 部分属于最近的 if 部分。
否则,您可以这样写:
if(y<0)
{
if(y>0) x=3;
}
else x=5;
在这种情况下,statement 是带有嵌套的 if 语句而没有 else 部分的复合语句。
{
if(y>0) x=3;
}
英文:
The if statements is defined the following way (for simplicity I am using the C grammar)
selection-statement:
if ( expression ) statement
if ( expression ) statement else statement
As you can see, the else part can not exist as a separate statement without the if part.
So, according to the definition, this if statement:
if(y<0) ...
can be rewritten like:
if(y<0) statement;
The statement can be any statement, including another if statement:
if(y<0) if(y>0) x=3; else x=5;
That is, the else part belongs to the closest if part.
Otherwise, you could write:
if(y<0)
{
if(y>0) x=3;
}
else x=5;
In this case, the statement is the compound statement with the enclosed if statement without the else part.
{
if(y>0) x=3;
}
答案4
得分: 2
以下是您要翻译的代码部分:
如果你像要求逻辑解释一样,为什么事情是它们所以让我们看看这段代码:
if( condition1 )
if( condition2 ) x = 1;
else x = 2;
else x = 3;
如果它按照你建议或期望的方式工作,那么注释掉 `else x = 3;` 这一行将使语句 `else x = 2;` 神奇地从 `if( condition2 )` 跳转到 `if( condition1 )`,而 `else x = 2` 应该属于取决于 `else x = 3;` 是否存在,这是一个非常不好的做法。但如果你有疑虑,可以使用 `{}` 来清晰明确地表达你的需求:
if( condition1 ) {
if( condition2 ) x = 1;
}
else x = 2;
英文:
As if you are asking for logical explanation why things they are let's look into this code:
if( condition1 )
if( condition2 ) x = 1;
else x = 2;
else x = 3;
if it would work as you suggested or expected then commenting out line else x = 3; would make statement else x = 2; magically jump from if( condition2 ) to if( condition1 ) and where else x = 2 belongs to would depend of existence of else x = 3; which is a very bad practice. But if you are in doubt use {} to express what you need clearly and unambiguous way:
if( condition1 ) {
if( condition2 ) x = 1;
}
else x = 2;
答案5
得分: 2
以下是要翻译的代码部分:
if(a) handle_a();
else if(b) handle_b();
else if(c) handle_c();
else handle_other();
这实际上等同于:
if(a) {
handle_a();
} else {
if(b) {
handle_b();
} else {
if(c) {
handle_c();
} else {
handle_other();
}
}
}
C 和 C++ 中的 if..else 的结合规则(以及其他一些语言)旨在支持if..else if 链,而不需要过多的嵌套(视觉上)。 C 通过引入一个规则,即 else 变为最接近的前面的 if 的 else,实现了这一行为,这使得 if(a); if (b); else c(); 具有特定的行为,虽然不特别有用或明显,但保持了规则的简洁。
英文:
The rules of associativity for if..else in C and C++ (and several other languages) are designed to support if..else if chains without excessive (visual) nesting:
if(a) handle_a();
else if(b) handle_b();
else if(c) handle_c();
else handle_other();
which is actually:
if(a) {
handle_a();
} else {
if(b) {
handle_b();
} else {
if(c) {
handle_c();
} else {
handle_other();
}
}
}
It's not too hard to design a syntax in which the less-indented version works properly, simply by special casing else if (as many other languages do, generally by having a special elseif keyword), but C accomplishes this behavior more elegantly, by introducing a rule that an else becomes the else for the closest preceding if. That leads to a specific behavior of if(a); if (b); else c(); which isn't particularly useful or obvious, but it keeps the rules simple(r).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论