在C语言中,”else”块与”if”块的关联。

huangapple go评论50阅读模式
英文:

Association of else block with if block in C

问题

我有如下的代码片段。有人能解释一下为什么 else 块与嵌套的 if 块关联在一起吗?以下代码段的输出是 1。我执行了代码,但无法理解为什么块的执行顺序如下。

更新:这是我在一家公司以前年度面试题中找到的问题。我总是在我的 ifelse 块周围使用括号。现在我明白为什么整个块没有执行。

谢谢大家的回答 在C语言中,”else”块与”if”块的关联。

英文:

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 在C语言中,”else”块与”if”块的关联。

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 &lt; 0)         // false, so it jumps directly here
        if (y &gt; 0)     //                                |
            x = 3;     //                                |
        else           //                                |
            x = 5;     //                                |
    printf(&quot;%d&quot;, x);   // &lt;------------------------------+

Adding braces makes it even clearer. The below has exactly the same meaning as your original code:

    int x = 1, y = 1;

    if (y &lt; 0) {
        if (y &gt; 0) {
            x = 3;
        } else {
            x = 5;
        }
    }
    printf(&quot;%d&quot;, x);

That is, if(condition) &lt;statement&gt; else &lt;statement&gt;. The &lt;statement&gt; 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 ) statement else 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) 将具有没有 elseif 形式。在后一种情况下,父 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>
> &nbsp;&nbsp;&nbsp;&nbsp;if ( expression ) statement<br>
> &nbsp;&nbsp;&nbsp;&nbsp;if ( expression ) statement else statement<br>
> &nbsp;&nbsp;&nbsp;&nbsp;switch ( expression ) statement

With this grammar, if(y&lt;0) if(y&gt;0) x=3; else x=5; may be parsed as if(y&gt;0) x=3; else x=5; being one statement that is “if ( expression ) statement else statement”, or it may be parsed with if(y&gt;0) x=3; being one statement that is if ( expression ) statement. In the former case, the parent if(y&gt;0) would have the if form without an else. In the latter case, the parent if(y&gt;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&lt;0) ...

can be rewritten like:

if(y&lt;0) statement;

The statement can be any statement, including another if statement:

if(y&lt;0) if(y&gt;0) x=3; else x=5;

That is, the else part belongs to the closest if part.

Otherwise, you could write:

if(y&lt;0) 
{ 
    if(y&gt;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&gt;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 变为最接近的前面的 ifelse,实现了这一行为,这使得 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).

huangapple
  • 本文由 发表于 2023年4月7日 00:28:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/75951744.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定