2009-02-01 38 views
32

什麼是匿名{}用C語言風格(C,C++,C#)塊的目的C風格語言中匿名{}塊的用途是什麼?

示例 -



void function() 
{ 

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

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

} 

編輯 - 感謝所有出色的答案!

+0

爲了完整起見,你也可以用Java來做到這一點。 – 2010-06-08 06:20:45

+0

使用範圍鎖定類鎖定:http://stackoverflow.com/questions/500006/what-is-the-purpose-of-anonymous-blocks-in-c-style-languages/4133914#4133914 – 2010-11-09 13:05:17

回答

61

它將變量的範圍限制在{}內的塊中。

+1

+1簡短而準確的答案。 – 2011-05-05 08:59:21

3

據我瞭解,他們只是作爲範圍。它們允許您在父/同級作用域中重用變量名稱,這可能會不時有用。

編輯:這個問題實際上已在another Stack Overflow question回答。希望有所幫助。

4

它們經常用於作用域變量,因此變量對於由大括號定義的任意塊是局部的。在你的例子中,變量i和k不能在它們的大括號之外訪問,所以它們不能以任何偷偷摸摸的方式修改,並且這些變量名可以在代碼中的其他地方重新使用。使用花括號創建局部範圍的另一個好處是,在使用垃圾收集的語言中,垃圾收集器知道清理超出範圍的變量是安全的。這在C/C++中不可用,但我相信它應該在C#中。

想一想,它的一個簡單方法是花括號定義一段原子代碼,有點像名稱空間,函數或方法,但不必實際創建一個名稱空間,函數或方法。

19

方括號指定一個範圍區域 - 在括號內聲明的任何東西在它們之外是不可見的。此外,在C++中,分配給堆棧的對象(例如,不使用'new')將在超出作用域時被破壞。

在某些情況下,它也可以突出顯示作者認爲值得關注的功能的特定部分。這是否是一個好用是有爭議的,但我已經看到它完成了。

6

{ ... }開闢了一個新的範圍

在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); 
     // ... 
    } 
} 

這將讓事情分開,以便可以很容易地找出不同的積木。您可以使用具有相同名稱的變量,如上面的代碼所示,因爲它們在其範圍之外不可見,因此它們不會相互衝突。

4

你是做兩件事情。

  1. 您正在對該塊中的變量強制作用域限制。
  2. 您正在啓用兄弟代碼塊使用相同的變量名。
+0

2隱含地從1 – 2009-02-01 14:26:05

2

這是關於範圍,它指的是變量和方法的程序到程序的其他部分的一個部分的曝光率,請考慮下面的例子:

int a=25; 
int b=30; 
{ //at this point, a=25, b=30 
    a*=2; //a=50, b=30 
    b /= 2; //a=50,b=15 
    int a = b*b; //a=225,b=15 <--- this new a it's 
        //     declared on the inner scope 
} 
//a = 50, b = 15 
12

他們往往有用RAII這意味着當對象超出範圍時,將會釋放給定的資源。例如:

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

如所提到的以前的海報,它限制了使用可變的,以在其聲明的範圍。

在垃圾收集的語言,如C#和Java,它也允許垃圾收集器以回收通過的範圍內使用的任何變量使用(雖然變量設置到零將具有相同的效果)存儲器。

{ 
    int[] myArray = new int[1000]; 
    ... // Do some work 
} 
// The garbage collector can now reclaim the memory used by myArray 
+0

實際上,根據GC的實現,JIT應該已經知道該變量沒有更多的讀取,因此它已經有資格收集。 – 2009-02-01 08:59:05

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 
} 
2

如果僅限於ANSI C,那麼它們可以被用來接近,你使用它們聲明變量:

int main() { 
    /* Blah blah blah. */ 
    { 
     int i; 
     for (i = 0; i < 10; ++i) { 
     } 
    } 
} 

不neccessary擁有現代化的C編譯器雖然。

+0

是的,有時它只是一個視覺事物。另外值得注意的是,大括號內的任何內容都被認爲是「僅接受單一語句」的語法結構的「聲明」。 – gbarry 2009-02-01 04:17:56

+0

你的意思是在C++中不需要,對吧? – 2010-11-09 12:52:49

+0

@Valentin:是的,在C++中,你可以在任何地方聲明變量,而不僅僅是在塊的頂部。 – Bernard 2010-11-11 07:30:43

5

通過創建一個新的範圍,他們可以用在switch語句來定義局部變量。

例如

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

switch (i) 
{ 
    case 0 : 
    { 
     int j = 0; // ok! 
    } 
    break; 
+0

@Ferrucio:不僅在switch語句中。在C中,變量應該在任何指令前的範圍內定義。所以,如果你有一個大功能,並需要一個臨時變量進行計算,你可以在函數的任何地方打開一個新的範圍並定義你的臨時變量。 – 2010-11-09 12:50:25

7

另一個常見用途是用OpenGL的glPushMatrix()glPopMatrix()函數來創建與所述矩陣堆棧邏輯塊:

glPushMatrix(); 
{ 
    glTranslate(...); 
    glPushMatrix(); 
    { 
     glRotate(...); 
     // draw some stuff 
    } 
    glPopMatrix(); 
    // maybe draw some more stuff 
} 
glPopMatrix(); 
3
作用域

當然。 (那匹馬是否被打死了?)

但是,如果你看一下語言的定義,你看到這樣的圖案:

  • 如果表達   聲明
  • 如果表達式   語句   別的   語句
  • 開關表達   語句
  • 表達   語句
  •   語句   表達;

它簡化了語言的語法複合語句只是幾種可能語句的之一。


複合語句:  {語句列表選擇}

語句列表

  • 狀態換貨
  • 語句列表   聲明

聲明

  • 標記語句
  • 表達式語句
  • 複合語句
  • 選擇語句
  • 迭代語句
  • 跳轉語句
  • 聲明語句
  • 試塊
0

我將它用於需要臨時變量的代碼塊。

0

用於定義C++中關鍵部分的有用use-cas ihmo是。 例如: -

int MyClass::foo() 
{  
    // stuff uncritical for multithreading 
    ... 
    { 
     someKindOfScopeLock lock(&mutexForThisCriticalResource); 
     // stuff critical for multithreading! 
    } 
    // stuff uncritical for multithreading 
    ...  
} 

使用匿名範圍沒有必要調用互斥的鎖定/解鎖或明確一個信號。