"##"與"#"
看一個(gè)栗子??:
#include <iostream>
int main(int argc, char** argv) {
float dataA[2][2] = {{1,2}, {3,4}};
float dataB[2][2] = {{5,6}, {7,8}};
#define ELEMENT(w,h) \
a##w##h = dataA[w][h], \
b##w##h = dataB[w][h]
float ELEMENT(0,0),ELEMENT(0,1),ELEMENT(1,0),ELEMENT(1,1);
#undef ELEMENT
std::cout << a00 << " " << a01 << " " << b00 << " " << b01 << std::endl;
}
上述示例中殖卑,ELEMENT(w,h)
宏中“a##w##h
”和"b##w##h
"表示字符串"a00"(w=0,h=0)或"b11"(w=1,h=1),"##
"符號(hào)把兩個(gè)宏參數(shù)貼合在一起;
相對(duì)地坊萝,“#
”可以把宏參數(shù)變?yōu)橐粋€(gè)字符串孵稽,以下是一個(gè)將枚舉轉(zhuǎn)換為字符串的示例:
#include <iostream>
enum Color {
RED, YELLOW, GREEN
};
std::string get_color_str(Color c) {
#define STR(c) \
case c: \
return #c; \
break
switch(c) {
STR(RED);
STR(YELLOW);
STR(GREEN);
}
#undef STR
}
int main(int argc, char** argv) {
Color c = RED;
std::cout << get_color_str(c) << std::endl;
}
為什么要即時(shí)#undef
#define
是在編譯期展開的,類似于文件的查找替換十偶,它不尊重任何C++范圍菩鲜。所以為了避免宏的泛濫,要給宏手動(dòng)增加作用域扯键,即#define
和#undef
之間的范圍睦袖,同時(shí)為了避免錯(cuò)誤,應(yīng)當(dāng)盡量以大寫來命名宏荣刑。
do{...}while(0)技巧
do{...}while(0)是一個(gè)非常好用的增加程序健壯性的技巧馅笙,能夠避免很多意想不到的問題,參見https://dream-notes.readthedocs.io/language/cpp/cpp_micro.html