点击查看c语言高手hwTony的宏 vs. 模版

这个小c语言项目hwTony较多得用到了宏,在我的印象里,宏是小函数的替代品,它的出现是为了减少函数调用的压栈出栈开销,而且宏一般都短小精悍,从没想到还有这方面的用处。

以下代码纯属编程爱好者学习和交流使用,可能涉及商业机密,请在看完30分钟后忘掉,否则一切后果得我来负责咳咳。

void m_n_snmp_setting()
{
BEGIN_MENU(“Main menu/Network/SNMP Setting”)
ADD_MENU_ITEM(“Trap”, m_n_s_trap)
ADD_MENU_ITEM(“SNMP Community”, m_n_s_snmp_community)
END_MENU()
}

在这个小函数里,BEGIN_MENU创建了一个struct,struct体以ADD_MENU_ITEM内容来填充,在END_MENU里关闭这个struct并且启动一个menu_loop函数,在menu_loop函数里根据BEGIN_MENU的Menu title打印菜单的title,根据struct的值打印出菜单,并且进入循环,根据用户的选择进入ADD_MENU_ITEM对应的函数,或者退出。在这个函数里没有任何变量定义,纯粹是自然语言的描述。代码非常整洁并且利于维护。

在那天hwTony给我介绍这个技巧时我才意识到,我在VC里面早就看过这种语法,在用CodeWarrior编写公交通的程序时也用到这种宏,我就照抄他的Demo,
比如
// Event map
BEGIN_EVENT_MAP(CModalForm)
EVENT_MAP_COMMAND_ENTRY(AboutOKButton, OnOK)
END_EVENT_MAP()

// Post-Event map
BEGIN_POST_EVENT_MAP(CModalForm)
POST_EVENT_MAP_ENTRY(frmOpenEvent, OnOpenPost)
END_POST_EVENT_MAP()
说实话,开始我很土得认为他是VC、CodeWarrior代码编辑器支持的特性,直到hwTony解释的时候我才知道是c语言的宏咳咳。

最后传授一个经验,问题的起因是由于上面的一个宏定义要涉及到多行代码,所以就使用了\来折行(VB是用 _ 咯),我们在gcc version 2.96下编译一切正常,但是到了gcc version 2.95.3下就出现了问题,根本不认这个\。最后不知道哪里来了灵感,把文件格式从PC改为UNIX(更改文件格式可使用EditPlus->Document->File format或者UltraEdit->File->Conversions或者sed命令),便顺利通过了编译。对于Linux和PC格式的文件区别,就是0D0A和0A的区别,像PERl是一定要求是UNIX格式的,所以如果在Linux下处理文本文件出了问题找不到原因时,要先确认一下文件格式的咯:)