C风格语言中匿名{}块的目的是什么?

use*_*106 37 c c# c++

C风格语言中的匿名{}块的目的是什么(C,C++,C#)

示例 -



void function()
{

  {
    int i = 0;
    i = i + 1;
  }

  {
    int k = 0;
    k = k + 1;
  }

}

Run Code Online (Sandbox Code Playgroud)

编辑 - 感谢所有优秀的答案!

17 *_* 26 69

它将变量的范围限制在{}内的块.


And*_*ant 20

括号指定范围区域 - 括号内声明的任何内容都是不可见的.

此外,在C++中,在堆栈上分配的对象(例如,不使用'new')将在超出范围时被破坏.

在某些情况下,它也可以是一种突出显示作者认为值得关注的功能的特定部分的方式.这是否是一个好的用途是有争议的,但我已经看到它完成.


Mar*_*ote 13

它们通常用于RAII目的,这意味着当对象超出范围时将释放给定资源.例如:

void function()
{
    {
        std::ofstream out( "file.txt" );
        out << "some data\n";
    }
    // You can be sure that "out" is closed here
}
Run Code Online (Sandbox Code Playgroud)


Ada*_*eld 7

另一个常见用途是使用OpenGL glPushMatrix()glPopMatrix()函数来创建与矩阵堆栈相关的逻辑块:

glPushMatrix();
{
    glTranslate(...);
    glPushMatrix();
    {
        glRotate(...);
        // draw some stuff
    }
    glPopMatrix();
    // maybe draw some more stuff
}
glPopMatrix();
Run Code Online (Sandbox Code Playgroud)


Joh*_*itb 6

{ ... } 开辟了一个新的范围

在C++中,您可以像这样使用它们:

void function() {
    // ...
    {
        // lock some mutex.
        mutex_locker lock(m_mutex);
        // ...
    }
    // ...
}
Run Code Online (Sandbox Code Playgroud)

一旦控件离开块,互斥锁柜就会被破坏.在它的析构函数中,它会自动解锁它所连接的互斥锁.这经常被做,并且被称为RAII(资源获取是初始化)以及SBRM(范围限制资源管理).另一个常见的应用是分配内存,然后在析构函数中再次释放该内存.

另一个目的是做几件类似的事情:

void function() {
    // set up timer A
    {
        int config = get_config(TIMER_A);
        // ... 
    } 

    // set up timer B
    {
        int config = get_config(TIMER_B);
        // ...
    } 
}
Run Code Online (Sandbox Code Playgroud)

它会将事物分开,这样就可以很容易地找出不同的构建块.您可以使用具有相同名称的变量,如上面的代码,因为它们在其范围之外不可见,因此它们不会相互冲突.


yfe*_*lum 6

class ExpensiveObject {
public:
    ExpensiveObject() {
        // acquire a resource
    }
    ~ExpensiveObject() {
        // release the resource
    }
}

int main() {
    // some initial processing
    {
        ExpensiveObject obj;
        // do some expensive stuff with the obj
    } // don't worry, the variable's scope ended, so the destructor was called, and the resources were released
    // some final processing
}
Run Code Online (Sandbox Code Playgroud)


Fer*_*cio 6

通过创建新范围,可以使用它们在switch语句中定义局部变量.

例如

switch (i)
{
    case 0 :
        int j = 0;   // error!
        break;
Run Code Online (Sandbox Code Playgroud)

switch (i)
{
    case 0 :
    {
        int j = 0;   // ok!
    }
    break;
Run Code Online (Sandbox Code Playgroud)


Mr.*_*Ree 5

当然是范围界定。(那匹马被打死了吗?)

但如果你查看语言定义,你会看到如下模式:

  • if 表达式   语句
  • if ( 表达式 )   语句   else   语句
  • switch 表达式   语句
  • while 表达式   语句
  • do   语句   while ( 表达式 ) ;

它简化了语言语法,复合语句只是几个可能的语句之一。


复合语句:   { 语句列表opt }

声明列表

  • 陈述
  • 语句列表   语句

陈述

  • 标记语句
  • 表达式语句
  • 复合语句
  • 选择声明
  • 迭代语句
  • 跳转语句
  • 声明-声明
  • 尝试块

  • 是的,人们经常忘记 `if (...) {...} else {...}` 或 `for(...) {...}` 也使用匿名块。事实上,这个问题的措辞就好像基于这个前提。 (3认同)