在C/C++中經常可以看到各種宏,現對宏的妙用做一些使用總結。
一、防止頭文件的重複包含:
#ifndef __XXXX_H__
#define __XXXX_H__
......
#endif
二、條件編譯,根據條件選擇性編譯插入代碼:
#ifdef _UNICODE
#define _T(x) L##x //如果定義了_UNICODE宏則使用L把字符串連接起來, 譬如L"ABC"
#else
#define _T(x) x
#endif
三、定義常量,但在C++中不建議使用宏來定義常量,最好使用關鍵字const:
#define PI 3.14
#define ME "我"
四、定義宏替換函數:
#ifdef _ADD_
#define Calc(x, y) Add(x, y)//如果定義了_ADD_,則調用Sub函數,否則調用Div函數
#else
#define Calc(x, y) Sub(x, y)
#endif
int Add(int x, int y)
{
return x + y;
}
int Sub(int x, int y)
{
return x - y;
}
int main()
{
int a = 3, b = 2;
std::cout << "result: " << Calc(3, 2) << std::endl;
return 0;
}
五、使用宏定義函數:
譬如我們使用GetProcAddress獲取函數指針時,如果使用定義宏函數就可以簡化函數指針的獲取
typedef int (_stdcall *PAdd)(int a, int b);//定義函數指針類型, 注意這裏的"PAdd"中的'P'要與宏中的一致
typedef int (_stdcall *PSub)(int a, int b);
//獲取函數指針
#define GetFunctionPointer(h, x)\
{\
if(NULL == h)\
{\
return FALSE;\
}\
x = (P##x)::GetProcAddress(h, #x);\
}\
int main()
{
HMODULE hModule = NULL;
hModule = ::LoadLibrary(dynamic_lib_path);
PAdd Add;//這裏的定義的函數指針Add與動態庫內導出的函數名稱是一致的
PSub Sub;
GetFunctionPointer(hModule, Add);
GetFunctionPointer(hModule, Sub);
...//省略
return 0;
}
六、##與#組合宏
#define _LINK_(x, y) x##y //把x y進行連接在一起
#define TO_STR(x) #x //把x加雙引號""
int main()
{
std::cout << _LINK_(13, 14) << std::endl; //輸出1314
std::cout << _LINK_("A", "B") << std::endl; //輸出AB
std::cout << TO_STR(1314) << std::endl; //輸出1314
std::cout << TO_STR("AB") << std::endl; //輸出"AB"
return 0;
}
......
以上幾種宏的使用是經常會用的,當然還有變參宏等等其他一些用法,可以參考MSDN。