{}之前没有任何关键字的目的是什么?

时间:2015-12-10 14:37:59

标签: c++ c++11

今天,我花了4个小时调试一个小错误:

while (++i < nb); //Notice this semicolon that i put by mistake
{
    do_stuff();
}

我不知道为什么do_stuff没有执行足够的时间。 当我看到自己的错误时,我想知道:为什么有人会在代码中间将代码括在括号中? 有人可以解释一下吗?这是C语言演变的方式吗? (我知道由于复古兼容性原因,C的BNF包含一些奇怪的东西) 你是否认为循环中的预增量是一件坏事,我应该像上面那样写呢?

while (i < nb)
{
    do_stuff();
    i += 1;
}

5 个答案:

答案 0 :(得分:6)

  

为什么有人会将代码括在函数中间的大括号中?

这根本不是一个奇怪的想法,但它引入了一个范围,如下例所示:

void foo () {
    int a;
    {          // start a new scope
        int b = 1;
        std::cout << b << std::endl;
    }         // end of scope, i.e. b is out of scope now
    std::cout << a << std::endl;
    std::cout << b << std::endl; // error: unknown variable b !!
    double b = 0.0;              // just fine: declares a new variable
}

您可以使用它来本地化函数内部变量的可访问性。在示例中,b是临时的,并且通过将其声明放在本地范围内,我避免使用变量名称向函数范围发送垃圾邮件。

答案 1 :(得分:5)

您可能希望将所有逻辑放在while中并故意省略body。有些编译器会警告你,即。铛:

main.cpp:18:17: warning: while loop has empty body [-Wempty-body]
while (++i < nb); //Notice this semicolon that i put by mistake
                ^
main.cpp:18:17: note: put the semicolon on a separate line to silence this warning

介绍本地范围,例如:

{
   SomeClass aa;
   // some logic
}

也许并不罕见,你可能想要,在上面有人可能想要在结束括号之前调用析构函数 - 即。它会释放一些资源。

答案 2 :(得分:5)

我认为最常见的用途是与RAII一起使用:

{
   std::lock_guard<std::mutex> lock(mutex);
   // code inside block is under mutex lock
}
// here mutex is released

答案 3 :(得分:1)

本地范围有意义限制对象的生命周期和范围。它们对switch / case声明至关重要:

switch (i){
case 1:
    std::string s;
case 2:
    //does s exist or not? depends on the value of i
}

C ++说这是非常直接的。要解决此问题,请引入本地范围:

switch (i){
case 1:
{
    std::string s;
}//the lifetime of s ends here
case 2:
    //s is inaccessible
}

现在s仅限于其范围,您解决了s有时被定义的问题。

您可以根据需要添加任意数量的本地块,例如,这很好:

int main(){{{{{{{{{{
}}}}}}}}}}

答案 4 :(得分:0)

{<statement>*}(*表示零或更多)是C / C ++中的代码块,被视为单个语句。 语句类似于if (<expression>) <statement>(注意:这是一个递归语句)。 另一个陈述可能是<expression>;

同样{}会生成一个新范围。

这也是您可以在if语句中提供多个语句的原因。

如果有帮助,您可以将它们视为内联函数,并可访问当前范围。 (不是正确的查看方式,但足够接近)

以@ tobi303的答案为例。