C++ 速查手冊
14.2 - 巨集
前置處理器指令 #define 用來定義巨集 (macro) ,所謂的巨集是指文字的替換,舉例如下
#include <iostream>
#define DEMO 10
int main() {
std::cout << DEMO << std::endl;
#undef DEMO
//std::cout << DEMO << std::endl;
return 0;
}
/* 《程式語言教學誌》的範例程式
http://kaiching.org/
檔名:u1402_1.cpp
功能:示範 C++ 的前置處理器
作者:張凱慶*/
第 2 行定義了一個名為 DEMO 的巨集,這裡 DEMO 後空一格接整數 10 ,表示 DEMO 等於整數 10
#define DEMO 10
這意思是說,底下程式中只要出現 DEMO ,編譯前就會被置換成整數 10 ,像是程式中的這個部分
std::cout << DEMO << std::endl;
會變成
std::cout << 10 << std::endl;
然後才實際進行編譯,這樣的好處是可以把一些固定不變的字面常數用巨集取代,等同常數一樣。
下面的 #undef 指令則是取消 #define 的設定,因此底下第 9 行若是沒有註解化就會發生編譯錯誤。
編譯執行,結果如下
$ g++ u1402_1.cpp |
$ ./a.out |
10 |
$ |
巨集的另一個用途是取代簡單的函數,例如
#include <iostream>
#define Prints(arg) std::cout << #arg
int main() {
Prints(hello);
std::cout << std::endl;
return 0;
}
/* 《程式語言教學誌》的範例程式
http://kaiching.org/
檔名:u1402_2.cpp
功能:示範 C++ 的前置處理器
作者:張凱慶*/
第 2 行定義的巨集 Prints(arg) 使用一個參數 arg ,後面的 arg 要加上 # 符號
#define Prints(arg) std::cout << #arg
由於巨集是編譯前的文字替換,因此程式中這一行的 hello ,替換後等於字串 "hello"
Prints(hello);
編譯執行,結果如下
$ g++ u1402_2.cpp |
$ ./a.out |
hello |
$ |
除了 # 在巨集中表示參數外,也可使用 ## 連結識別名稱,例如
#include <iostream>
#define F(n, a) int f##n() {return a;}
F(test, 0);
F(function, 1);
F(rrr, 2);
int main() {
std::cout << ftest()<< std::endl;
std::cout << ffunction()<< std::endl;
std::cout << frrr() << std::endl;
return 0;
}
/* 《程式語言教學誌》的範例程式
http://kaiching.org/
檔名:u1402_3.cpp
功能:示範 C++ 的前置處理器
作者:張凱慶*/
第 2 行,巨集 F 有兩個參數 n 及 a ,呼叫 F 會產生以 f 開頭的新函數,新函數的識別字等於 fn ,然後回傳 a
#define F(n, a) int f##n() {return a;}
例如
F(test, 0);
因此就有了函數 ftest()
std::cout << ftest()<< std::endl;
編譯執行,結果如下
$ g++ u1402_3.cpp |
$ ./a.out |
0 |
1 |
2 |
$ |
相關教學影片