在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。