英文:
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)
statementelse
statement
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).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论