酷殼
下面這段程序是一個C語言的小技巧,其展示了如何把一個參數為結構體的函數轉成一個可變參數的函數,其中用到了宏和內建宏“__VA_ARGS__”,下面這段程序可以在GCC下正常編譯通過:
1234567891011121314151617181920 #include <stdio.h> #define func(...) myfunc((struct mystru){__VA_ARGS__}) struct mystru { const char *name; int number; }; void myfunc(struct mystru ms ) { printf("%s: %d ", ms.name ?: "untitled", ms.number); } int main(int argc, char **argv) { func("three", 3); func("hello"); func(.name = "zero"); func(.number = argc, .name = "argc",); func(.number = 42); return 0; }
從上面這段程序,我們可以看到一個叫 myfunc的函數,被func的宏改變了,本來myfunc需要的是一個叫mystru的結構,然而通過宏,我們把struct mystru的這個參數,變成了不定參數列表的一個函數。上面這段程序輸出入下,
three: 3
hello: 0
zero: 0
argc: 1
untitled: 42
雖然,這樣的用法並不好,但是你可以從另外一個方面了解一下這世上對C稀奇古怪的用法。 如果你把宏展開後,你就明的為什麼了。下面是宏展開的樣子:
12345 myfunc((struct mystru){"three", 3}); myfunc((struct mystru){"hello"}); myfunc((struct mystru){.name = "zero"}); myfunc((struct mystru){.number = argc, .name = "argc",}); myfunc((struct mystru){.number = 42});