塊 (C語言擴充)

(blocks)是由LLVM提出的類似於lambda表達式的非標準C語言擴充,亦可以應用於Objective-CC++中。它的語法類似於這些函數中的閉包,即由大括號包括的陳述式塊。

蘋果設計塊的一個目的是使設計基於Grand Central Dispatch線程結構的程式更容易[1][2],但塊是獨立於這一構架的,它也可以在其它程式中以與普通陳述式塊十分相似的方式應用。蘋果已經在蘋果修改版的GCC編譯器以及Clang LLVM編譯器前端中實現了這一特性;同時,LLVM計劃,包括了支援塊特性的執行時庫

與函數定義類似,塊可以有參數,也可以在其內部聲明私有變數。與普通的C函數定義不同,塊可以使用其上文中定義的變數。一個塊定義會產生一個不透明的值,該值同時包括了塊內代碼的參照和定義時棧內局部變數的快照(而非呼叫時)。塊可以在定義後被呼叫,其行為與函數指標相同。塊可以如同函數指標一般被賦值到變數中,作為函數的參數傳遞,但若塊需要在其被定義的範圍之外被使用時,程式設計師(或API)需要將該塊用特別的運算子(Block_copy)標記。

在定義塊之後,塊內的代碼可以在任何時間被呼叫,語法與呼叫函數相同。

範例

編輯

一個簡單的計數器的例子:[3]

#include <stdio.h>
#include <Block.h>
typedef int (^IntBlock)();

IntBlock MakeCounter(int start, int increment) {
	__block int i = start;
	
	return Block_copy( ^ {
		int ret = i;
		i += increment;
		return ret;
	});
	
}

int main(void) {
	IntBlock mycounter = MakeCounter(5, 2);
	printf("First call: %d\n", mycounter());
	printf("Second call: %d\n", mycounter());
	printf("Third call: %d\n", mycounter());
	
	/* 由于是复制的块,因此需要释放 */
	Block_release(mycounter);
	
	return 0;
}
/* Output:
	First call: 5
	Second call: 7
	Third call: 9
*/

編譯

編輯

Linux:

clang -fblocks blocks-test.c -lBlocksRuntime

與GCC巢狀函數的關係

編輯

塊在外表上與GCC的C擴充陳述式塊內的巢狀函數相似[4]。然而,巢狀函數與塊不同,在退出當前陳述式塊後就不能被呼叫了。

C語言標準

編輯

塊特性已經被提交到C標準委員會,作為C1x標準的一系列提案[5][6]

參見

編輯

參考資料

編輯
  1. ^ Apple Technical Brief on Grand Central Dispatch頁面存檔備份,存於互聯網檔案館), retrieved on June 9, 2009.
  2. ^ Mac OS X 10.6 Snow Leopard: the Ars Technica review: Blocks. [2010-09-15]. (原始內容存檔於2010-09-04). 
  3. ^ : Bengtsson, J. Programming with C Blocks on Apple Devices. [2010-09-15]. (原始內容存檔於2017-11-15). 
  4. ^ Nested Functions: Using the GNU Compiler Collection (GCC). [2010-09-15]. (原始內容存檔於2010-08-21). 
  5. ^ http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1370.pdf頁面存檔備份,存於互聯網檔案館) BLOCKS PROPOSAL, N1451
  6. ^ http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1451.pdf頁面存檔備份,存於互聯網檔案館) APPLE』S EXTENSIONS TO C, N1451

外部連結

編輯