什麼是匿名{}用C語言風格(C,C++,C#)塊的目的C風格語言中匿名{}塊的用途是什麼?
示例 -
void function()
{
{
int i = 0;
i = i + 1;
}
{
int k = 0;
k = k + 1;
}
}
編輯 - 感謝所有出色的答案!
什麼是匿名{}用C語言風格(C,C++,C#)塊的目的C風格語言中匿名{}塊的用途是什麼?
示例 -
void function()
{
{
int i = 0;
i = i + 1;
}
{
int k = 0;
k = k + 1;
}
}
編輯 - 感謝所有出色的答案!
它將變量的範圍限制在{}內的塊中。
+1簡短而準確的答案。 – 2011-05-05 08:59:21
據我瞭解,他們只是作爲範圍。它們允許您在父/同級作用域中重用變量名稱,這可能會不時有用。
編輯:這個問題實際上已在another Stack Overflow question回答。希望有所幫助。
它們經常用於作用域變量,因此變量對於由大括號定義的任意塊是局部的。在你的例子中,變量i和k不能在它們的大括號之外訪問,所以它們不能以任何偷偷摸摸的方式修改,並且這些變量名可以在代碼中的其他地方重新使用。使用花括號創建局部範圍的另一個好處是,在使用垃圾收集的語言中,垃圾收集器知道清理超出範圍的變量是安全的。這在C/C++中不可用,但我相信它應該在C#中。
想一想,它的一個簡單方法是花括號定義一段原子代碼,有點像名稱空間,函數或方法,但不必實際創建一個名稱空間,函數或方法。
方括號指定一個範圍區域 - 在括號內聲明的任何東西在它們之外是不可見的。此外,在C++中,分配給堆棧的對象(例如,不使用'new')將在超出作用域時被破壞。
在某些情況下,它也可以突出顯示作者認爲值得關注的功能的特定部分。這是否是一個好用是有爭議的,但我已經看到它完成了。
{ ... }
開闢了一個新的範圍
在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);
// ...
}
}
這將讓事情分開,以便可以很容易地找出不同的積木。您可以使用具有相同名稱的變量,如上面的代碼所示,因爲它們在其範圍之外不可見,因此它們不會相互衝突。
你是做兩件事情。
2隱含地從1 – 2009-02-01 14:26:05
這是關於範圍,它指的是變量和方法的程序到程序的其他部分的一個部分的曝光率,請考慮下面的例子:
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
他們往往有用RAII這意味着當對象超出範圍時,將會釋放給定的資源。例如:
void function()
{
{
std::ofstream out("file.txt");
out << "some data\n";
}
// You can be sure that "out" is closed here
}
如所提到的以前的海報,它限制了使用可變的,以在其聲明的範圍。
在垃圾收集的語言,如C#和Java,它也允許垃圾收集器以回收通過的範圍內使用的任何變量使用(雖然變量設置到零將具有相同的效果)存儲器。
{
int[] myArray = new int[1000];
... // Do some work
}
// The garbage collector can now reclaim the memory used by myArray
實際上,根據GC的實現,JIT應該已經知道該變量沒有更多的讀取,因此它已經有資格收集。 – 2009-02-01 08:59:05
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
}
如果僅限於ANSI C,那麼它們可以被用來接近,你使用它們聲明變量:
int main() {
/* Blah blah blah. */
{
int i;
for (i = 0; i < 10; ++i) {
}
}
}
不neccessary擁有現代化的C編譯器雖然。
通過創建一個新的範圍,他們可以用在switch語句來定義局部變量。
例如
switch (i)
{
case 0 :
int j = 0; // error!
break;
與
switch (i)
{
case 0 :
{
int j = 0; // ok!
}
break;
@Ferrucio:不僅在switch語句中。在C中,變量應該在任何指令前的範圍內定義。所以,如果你有一個大功能,並需要一個臨時變量進行計算,你可以在函數的任何地方打開一個新的範圍並定義你的臨時變量。 – 2010-11-09 12:50:25
另一個常見用途是用OpenGL的glPushMatrix()
和glPopMatrix()
函數來創建與所述矩陣堆棧邏輯塊:
glPushMatrix();
{
glTranslate(...);
glPushMatrix();
{
glRotate(...);
// draw some stuff
}
glPopMatrix();
// maybe draw some more stuff
}
glPopMatrix();
當然。 (那匹馬是否被打死了?)
但是,如果你看一下語言的定義,你看到這樣的圖案:
它簡化了語言的語法複合語句只是幾種可能語句的之一。
複合語句: {語句列表選擇}
語句列表:
聲明:
我將它用於需要臨時變量的代碼塊。
用於定義C++中關鍵部分的有用use-cas ihmo是。 例如: -
int MyClass::foo()
{
// stuff uncritical for multithreading
...
{
someKindOfScopeLock lock(&mutexForThisCriticalResource);
// stuff critical for multithreading!
}
// stuff uncritical for multithreading
...
}
使用匿名範圍沒有必要調用互斥的鎖定/解鎖或明確一個信號。
爲了完整起見,你也可以用Java來做到這一點。 – 2010-06-08 06:20:45
使用範圍鎖定類鎖定:http://stackoverflow.com/questions/500006/what-is-the-purpose-of-anonymous-blocks-in-c-style-languages/4133914#4133914 – 2010-11-09 13:05:17