【问题标题】:How do curly braces and scope wоrk in C?花括号和作用域如何在 C 中工作?
【发布时间】:2013-08-07 13:48:16
【问题描述】:

我目前正在尝试在业余时间学习一些 C 语言。我在 Java 方面有一些经验,因此我习惯于用花括号限制变量的范围。但我有点困惑,因为看起来 Brian W. Kernighan/Dennis M. Ritchie 的书“The C Programming Language”没有使用很多花括号,我认为使用它们是正常的(来自Java 视角)。例如。 1.6 书中代码所在:

while((c = getchar())) != EOF)
    if (c >= '0' && c <= '9')
        ++ndigit[c-'0'];
    else if() /*and so forth...*/
        ++nwhite;
    else
        ++nother;

从 Java 的角度来看,我习惯于只有第一个语句会运行,因为缺少花括号,但缩进表明一切都会运行(if、else if 和 else)。

所以我要问的是:这里会运行什么,为什么会运行? if、else if 和 else 都在 while 循环的范围内吗?是否有任何约定可以参考,我可以阅读以尝试更好地理解它?提前致谢。

【问题讨论】:

  • 根据经验,您可以说,如果您有一个像 if/while 这样的语句,那么紧随其后的行可以看作是语句的主体,在这种情况下,您有一个嵌套的建设
  • 在这里使用大括号在 Java 中是可选的,就像在 C 中一样:一个“if”语句may have an "else" clause,它有一个附加语句,它可能是另一个“if”,所以是一个完整的“if”级联。 .. else if ... else if ... else" 是 while 循环的单一主体语句。

标签: c scope curly-braces


【解决方案1】:

在 C 中,与在 Java 中一样,ìfwhile 有一个语句作为其主体,if 可以有一个可选的 else 子句,其中一个语句作为其主体。在大多数可以有一个语句的地方,你可以有一个语句块,它是一个用大括号括起来的语句列表。这在 C 中与在 Java 中没有什么不同。

为了避免歧义,如果有两个if和一个else,else被定义为引用最后一个。 IE。

if(a) x if(b) y else z

被定义为意味着

if(a) x { if(b) y else z }

而不是

if(a) x { if(b) y } else z

这里,x、y 和 z 是语句 - 也可以是语句块。

然而,说了这么多,省略大括号很容易出错,因此许多编码指南建议始终使用花括号。

【讨论】:

    【解决方案2】:

    如果 if 语句不包含花括号,则最多可以在其后内联一个分号,它会自动假定花括号如下:

    while((c = getchar())) != EOF){
        if (c >= '0' && c <= '9')
        {
            ++ndigit[c-'0'];
        }
        else if() /*and so forth...*/
        {
            ++nwhite;
        }
        else
        {
            ++nother; 
        }
     }
    

    所以这是有效的:

     while(true) i++;
    

    这应该是无效的:

     while(true) i++; break; printf("hello");
    
     if(true) printf("Hello"); break; 
    

    【讨论】:

    • 请修正你的缩进。
    • you can inline up to one semi colon after for (i = 0; i &lt; n; i++) for (int j = 0; j &lt; n; j++) ... 多于一个 分号。您要查找的术语是 statement
    • @amit 好吧,声明。此外,没有“假定分号”。根本没有“假设”,更不用说句法元素或标记。
    • 想帮助您进行缩进,但您拒绝了我的编辑...哦,好吧,那就留在您无法阅读的代码世界中...
    • 不是故意的,对不起!
    【解决方案3】:

    您可以将if/else if/else 指令视为一个块 - 它们实际上无法分割,else 不能单独存在。

    在旁注中,当您遇到类似情况时有时会感到困惑

    if(something)
       if (somethingOther)
         ....
    else
       .....
    

    如果您的代码足够长,您可能会混淆将else 附加到何处,因此最好始终使用大括号。正如评论中所述,else 始终附加到“最近的”if

    【讨论】:

    • 您的示例不应令人困惑 - else 始终对应于最里面的 if。
    • 我的意思是,在大型代码块中,格式不那么完美,可能会丢失,并不是说它在语法上模棱两可。已修复。
    • 谢谢。好吧,我仍然不完全同意——如果缩进是正确的,那么应该把它写得更深一层。随便...
    【解决方案4】:

    whileifelse ifelse 后跟一个语句。该语句可以是 C 的实际行,也可以是块语句(用大括号括起来)。 ifelse ifelse 被视为一个块。

    所以使用大括号,这将是等效的:

    while((c = getchar())) != EOF) {
        if (c >= '0' && c <= '9') {
            ++ndigit[c-'0'];
        }
        else if() {  /*and so forth...*/
            ++nwhite;
        }
        else {
            ++nother;
        }
    }
    

    【讨论】:

    • 事实上,在 Java 中也是如此。即使它容易出错,因此我倾向于不使用它。
    • 好的,非常感谢您的回答!但是我真的不明白为什么带有花括号的while循环中的所有内容都与没有花括号的循环相同。据我所知,while 循环中不止一个语句。 IE。如果(某事)++某事; ++其他东西;不允许,但是 while(1 == 1) if(something) { ++something; ++其他东西; } 被允许?如果这是正确的,那一定意味着对于花括号的 if 和 while 规则不同?
    • 实际上,if statement 本身(包括一个可选的 else 子句及其语句)就是一个语句。
    • 如我的回答中所述,花括号将多个语句组合在一起,就像一个语句一样。
    • ifelse ifelse 语句一起被视为一个大块。你可以再深入一点,所以嵌套的ifelse ifelse语句也算是一大块
    猜你喜欢
    • 2021-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-01
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多