前置處理器指令 #define 用來定義巨集 (macro) ,所謂的巨集是指文字的替換,舉例如下
001 | #include <iostream> |
002 | #define DEMO 10 |
003 | |
004 | int main() { |
005 | std::cout << DEMO |
006 | << std::endl; |
007 | |
008 | #undef DEMO |
009 | |
010 | //std::cout << DEMO |
011 | // << std::endl; |
012 | |
013 | return 0; |
014 | } |
015 | |
016 | /* Kaiching Chang |
017 | u1402_1.cpp |
018 | 2014-02 */ |
第 2 行定義了一個名為 DEMO 的巨集,這裡 DEMO 後空一格接整數 10 ,表示 DEMO 等於整數 10
002 | #define DEMO 10 |
這意思是說,底下程式中只要出現 DEMO ,編譯前就會被置換成整數 10 ,像是程式中的這個部分
005 | std::cout << DEMO |
會變成
005 | std::cout << 10 |
然後才實際進行編譯,這樣的好處是可以把一些固定不變的字面常數用巨集取代,等同常數一樣。
下面的 #undef 指令則是取消 #define 的設定,因此底下第 10 行若是沒有註解化就會發生編譯錯誤。
編譯執行,結果如下
$ g++ u1402_1.cpp |
$ ./a.out |
10 |
$ |
巨集的另一個用途是取代簡單的函數,例如
001 | #include <iostream> |
002 | #define Prints(arg) std::cout << #arg |
003 | |
004 | int main() { |
005 | Prints(hello); |
006 | std::cout << std::endl; |
007 | |
008 | return 0; |
009 | } |
010 | |
011 | /* Kaiching Chang |
012 | u1402_2.cpp |
013 | 2014-02 */ |
第 2 行定義的巨集 Prints(arg) 使用一個參數 arg ,後面的 arg 要加上 # 符號
002 | #define Prints(arg) std::cout << #arg |
由於巨集是編譯前的文字替換,因此程式中這一行的 hello ,替換後等於字串 "hello"
005 | Prints(hello); |
編譯執行,結果如下
$ g++ u1402_2.cpp |
$ ./a.out |
hello |
$ |
除了 # 在巨集中表示參數外,也可使用 ## 連結識別名稱,例如
001 | #include <iostream> |
002 | #define F(n, a) int f##n() {return a;} |
003 | |
004 | F(test, 0); |
005 | F(function, 1); |
006 | F(rrr, 2); |
007 | |
008 | int main() { |
009 | std::cout << ftest() |
010 | << std::endl; |
011 | std::cout << ffunction() |
012 | << std::endl; |
013 | std::cout << frrr() |
014 | << std::endl; |
015 | |
016 | return 0; |
017 | } |
018 | |
019 | /* Kaiching Chang |
020 | u1402_3.cpp |
021 | 2014-02 */ |
第 2 行,巨集 F 有兩個參數 n 及 a ,呼叫 F 會產生以 f 開頭的新函數,新函數的識別字等於 fn ,然後回傳 a
002 | #define F(n, a) int f##n() {return a;} |
例如
004 | F(test, 0); |
因此就有了函數 ftest()
009 | std::cout << ftest() |
編譯執行,結果如下
$ g++ u1402_3.cpp |
$ ./a.out |
0 |
1 |
2 |
$ |
continue ...
沒有留言:
張貼留言