C++ 速查手冊 V1.00 - 單元 14.2 - 巨集




前置處理器指令 #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 有兩個參數 na ,呼叫 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 ...

沒有留言: