# Compound Literals 複合字面值 ## 原理 C99 標準引入 **Compound Literals**: - **語法**: `(type_name){initializer_list}` 或 `(type_name[]){initializer_list}` - **功能**: 在程式碼中直接建立一個未命名(unnamed)的物件 (結構、陣列等),並回傳該物件的位址 (對於陣列,是首元素的位址)。 - **生命週期**: 若在函式內部使用,其生命週期通常與所在的區塊 (block scope) 相同。 ## 使用 Compound Literals 快速建立 Linked List 節點 ```c= struct llist { int val; struct llist *next; }; ``` 1. **預定義巨集** ```c=5 #define cons(x, y) (struct llist[]){x, y} ``` * 建立一個匿名的 `struct llist` **陣列**,該陣列只有一個元素。 * C 語言會使用 `x` 來初始化這個陣列首元素 (即第一個 `struct llist`) 的第一個成員 (`val`),並使用 `y` 來初始化第二個成員 (`next`)。 * 整個 Compound Literal 運算式的值是這個匿名陣列**首元素**的記憶體位址 (也就是一個 `struct llist *` 指標)。 * **效果**: `cons(x, y)` 建立了一個新的 `struct llist` 節點,其 `val` 為 `x`,`next` 為 `y`,並回傳指向這個新節點的指標。 4. **`main` 函式** ```c=6 int main() { // 使用 cons 巨集建立串列 (語法簡潔) struct llist *list = cons(9, cons(5, cons(4, cons(7, NULL)))); // 展開上面的巨集會得到 struct llist *list = (struct llist[]){9, (struct llist[]){5, (struct llist[]){4, (struct llist[]){7, ((void *)0)}}}}; struct llist *p = list; for (; p; p = p->next) printf("%d -> ", p->val); printf("\n"); return 0; } ``` * **串列建立**: * 建立串列 (9 -> 5 -> 4 -> 7 -> NULL)。 * 使用 `cons` 巨集,程式碼更易讀。 ## 重點總結 * **Compound Literals** 提供了一種在 C 程式碼中直接建立匿名物件 (尤其是結構或陣列) 的簡潔語法,並回傳其指標。 * 透過 `#define` 巨集可以將 Compound Literal 的使用包裝起來,提高程式碼可讀性 (如 `cons` 巨集)。 * 此範例展示了如何利用 Compound Literals 模擬函數式程式設計風格來建立連結串列。 ## 注意事項 * Compound Literals 是 C99 標準的一部分,需使用支援 C99 或更新標準的編譯器 (如 GCC, Clang)。