1) 宏中"#"和"##"的的简单用法:
“#” 可以把宏参数变成一个字符串。
“##” 可以把两个宏参数链接成一个符号。
例如:
#define STR(s) #s
#define CONNECT(a, b) { a##e##b}
int main()
{
printf(STR(abc)); // 输出字符串"abc"
printf("%d/n", CONNECT (1,3)); // 1e3 输出:1000
return 0;
}
2)展开宏代码
据大家所知道的,编译器在编译源文件前先将宏代码展开,再编译。由于宏不利于阅读,很难检查出它的正确性。若我们能把宏展开成的代码输出来,岂不很好,下面简单的讲一下怎么显示出宏展开代码。
#define TO_STRING(x) _TO_STRING(x)
#define _TO_STRING(x) #x
为什么要多_TO_STRING层呢? 目的是展开TO_STRING(x) 时,先将x宏展开。若直接用_TO_STRING的话,直接将传入的参数形成字符串。
例如:利用TO_STRING查看MFC中IMPLEMENT_DYNCREATE宏展开后的代码:
#pragma message(TO_STRING(IMPLEMENT_DYNCREATE(QcFrameWnd, CFrameWndEx)))
在输出窗口中就会输入IMPLEMENT_DYNCREATE(QcFrameWnd, CFrameWndEx)展开后的代码:
CObject* __stdcall QcFrameWnd::CreateObject()
{
return new QcFrameWnd;
}
CRuntimeClass* __stdcall QcFrameWnd::_GetBaseClass()
{
return (CFrameWndEx::GetThisClass());
}
__declspec(selectany) const CRuntimeClass QcFrameWnd::classQcFrameWnd =
{
"QcFrameWnd", sizeof(class QcFrameWnd), 0xFFFF, QcFrameWnd::CreateObject, &QcFrameWnd::_GetBaseClass, 0, 0
};
CRuntimeClass* __stdcall QcFrameWnd::GetThisClass()
{
return ((CRuntimeClass*)(&QcFrameWnd::classQcFrameWnd));
}
CRuntimeClass* QcFrameWnd::GetRuntimeClass() const
{
return ((CRuntimeClass*)(&QcFrameWnd::classQcFrameWnd));
}