今天,我花了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;
}
答案 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的答案为例。