Каково назначение анонимных блоков {} в языках стиля C? - PullRequest
35 голосов
/ 01 февраля 2009

Для чего предназначены анонимные блоки {} в языках стиля C (C, C ++, C #)

Пример -



void function()
{

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

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

}

Редактировать - Спасибо за все отличные ответы!

Ответы [ 16 ]

66 голосов
/ 01 февраля 2009

Ограничивает область видимости переменных блоком внутри {}.

20 голосов
/ 01 февраля 2009

Скобки обозначают область видимости - все, что объявлено в скобках, невидимо вне их.

Кроме того, в C ++ объект, размещенный в стеке (например, без использования 'new'), будет разрушен, когда он выйдет из области видимости.

В некоторых случаях это также может быть способ выделить конкретную часть функции, которая, по мнению автора, заслуживает внимания тех, кто смотрит на источник. Является ли это хорошо использовать или нет, является спорным, но я видел, как это делается.

13 голосов
/ 01 февраля 2009

Они часто полезны для RAII целей, что означает, что данный ресурс будет освобожден, когда объект выйдет из области видимости. Например:

void function()
{
    {
        std::ofstream out( "file.txt" );
        out << "some data\n";
    }
    // You can be sure that "out" is closed here
}
7 голосов
/ 01 февраля 2009

Другое распространенное использование - функции glPushMatrix() и glPopMatrix() OpenGL для создания логических блоков, связанных со стеком матрицы:

glPushMatrix();
{
    glTranslate(...);
    glPushMatrix();
    {
        glRotate(...);
        // draw some stuff
    }
    glPopMatrix();
    // maybe draw some more stuff
}
glPopMatrix();
6 голосов
/ 01 февраля 2009
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
}
6 голосов
/ 01 февраля 2009

{ ... } открывает новую область действия

В C ++ вы можете использовать их следующим образом:

void function() {
    // ...
    {
        // lock some mutex.
        mutex_locker lock(m_mutex);
        // ...
    }
    // ...
}

Как только управление выходит из блока, локатор мьютекса уничтожается. И в своем деструкторе он автоматически разблокирует мьютекс, к которому он подключен. Это очень часто делается и называется RAII (получение ресурсов является инициализацией), а также SBRM (управление ресурсами, ограниченным областью действия). Другим распространенным приложением является выделение памяти, а затем в деструкторе снова освободить эту память.

Другая цель состоит в том, чтобы сделать несколько подобных вещей:

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

    // set up timer B
    {
        int config = get_config(TIMER_B);
        // ...
    } 
}

Это будет держать вещи отдельно, чтобы можно было легко найти различные строительные блоки. Вы можете использовать переменные с одинаковыми именами, как в коде выше, потому что они не видны за пределами своей области видимости, поэтому они не конфликтуют друг с другом.

5 голосов
/ 01 февраля 2009

Создавая новую область, они могут использоваться для определения локальных переменных в операторе switch.

, например

switch (i)
{
    case 0 :
        int j = 0;   // error!
        break;

против

switch (i)
{
    case 0 :
    {
        int j = 0;   // ok!
    }
    break;
4 голосов
/ 01 февраля 2009

Вы делаете две вещи.

  1. Вы вводите ограничение области действия для переменных в этом блоке.
  2. Вы разрешаете блокам кода одного уровня использовать одинаковые имена переменных.
4 голосов
/ 01 февраля 2009

Они очень часто используются для определения области видимости переменных, так что переменные являются локальными для произвольного блока, определенного фигурными скобками. В вашем примере переменные i и k недоступны за пределами заключенных в них фигурных скобок, поэтому они не могут быть изменены каким-либо хитрым способом, и эти имена переменных могут быть повторно использованы в другом месте вашего кода. Другое преимущество использования фигурных скобок для создания локальной области видимости состоит в том, что в языках с сборкой мусора сборщик мусора знает, что безопасно очищать переменные вне области видимости. Это не доступно в C / C ++, но я считаю, что это должно быть в C #.

Один простой способ думать об этом состоит в том, что фигурные скобки определяют элементарный фрагмент кода, вроде пространства имен, функции или метода, но без необходимости фактически создавать пространство имен, функцию или метод.

3 голосов
/ 01 февраля 2009

Обзор конечно. (Эта лошадь уже была избита до смерти?)

Но если вы посмотрите на определение языка, вы увидите такие шаблоны:

  • если ( выражение ) выражение
  • if ( выражение ) оператор else оператор
  • переключатель ( выражение ) оператор
  • while ( выражение ) выражение
  • do оператор while ( выражение ) ;

Упрощает синтаксис языка, что составной оператор является лишь одним из нескольких возможных операторов .


составной оператор : { список операторов opt }

оператор-лист

  • оператор
  • ведомость-список ведомость

оператор

  • меченый-оператор
  • выражение-оператор
  • соединение-оператор
  • выбор-оператор
  • итерация-оператор
  • перепрыжка заявление
  • декларация-заявление
  • примерка блок
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...