塊 (C語言擴充)
外觀
塊(blocks)是由LLVM提出的類似於lambda表達式的非標準C語言擴充,亦可以應用於Objective-C與C++中。它的語法類似於這些函數中的閉包,即由大括號包括的陳述式塊。
蘋果設計塊的一個目的是使設計基於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]。
參見
[編輯]參考資料
[編輯]- ^ Apple Technical Brief on Grand Central Dispatch (頁面存檔備份,存於互聯網檔案館), retrieved on June 9, 2009.
- ^ Mac OS X 10.6 Snow Leopard: the Ars Technica review: Blocks. [2010-09-15]. (原始內容存檔於2010-09-04).
- ^ : Bengtsson, J. Programming with C Blocks on Apple Devices. [2010-09-15]. (原始內容存檔於2017-11-15).
- ^ Nested Functions: Using the GNU Compiler Collection (GCC). [2010-09-15]. (原始內容存檔於2010-08-21).
- ^ http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1370.pdf (頁面存檔備份,存於互聯網檔案館) BLOCKS PROPOSAL, N1451
- ^ http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1451.pdf (頁面存檔備份,存於互聯網檔案館) APPLE』S EXTENSIONS TO C, N1451
外部連結
[編輯]- Clang Language Extensions: Blocks. LLVM Project. [2010-06-09]. (原始內容存檔於2010-07-16).
- "compiler-rt" Blocks Runtime Library | Blocks Runtime. LLVM Project. [2011-03-25]. (原始內容存檔於2009-07-06).