多行宏定义中的注释问题

早上在写代码时遇到这样一个问题:即如何在一个拥有多行的宏定义中做注释?,这里把方法演化的过程贴出来,可能对某些朋友有些借鉴意义。

宏定义高深莫测,而且是比较细节的东西,详细说明请参见"C参考手册"之类的书籍。

在我的代码中,我大致要做这样一个简单的事情:printf("%s%s%s\n", "hello", "macro", "yeah!"); "%s%s%s\n"这个字符串中每一项输出都有一定的含义,而且在真实代码里,这个串中的输出项可不止3个,所以一个直接的想法就是将其定义为一个宏。

#define STR_OUTPUT_FORMAT_V0  "%s%s%s\n"
printf(STR_OUTPUT_FORMAT_V0, "hello ", "macro, ", "yeah!");
程序输出:hello macro, yeah!

由于真实代码中这个串很长,所以打算美化一下格式,定义成下面的样子:
#define STR_OUTPUT_FORMAT_V1  "%s\
                               %s\
                               %s\n"
printf(STR_OUTPUT_FORMAT_V1, "hello ", "macro, ", "yeah!");
程序输出:hello                                macro,                                yeah!

这样的定义显然不对,也在我意料之中,续行符将空格也续到格式串中了,导致输出的结果中带有大量空格。

改进一下,利用C语言的字符串自动连接语法。
#define STR_OUTPUT_FORMAT_V2  "%s"\
                              "%s"\
                              "%s\n"
printf(STR_OUTPUT_FORMAT_V2, "hello ", "macro, ", "yeah!");
程序输出:hello macro, yeah!

现在的问题是如何在这样一个多行的宏定义里加入注释,字段含义特殊,加上注释有利于以后维护以及别人阅读你的代码,否则一堆%s%s,让人看了就头痛。先这么加试试:
#define STR_OUTPUT_FORMAT_E1  "%s"\   /* comment1 */
                              "%s"\   /* comment2 */
                              "%s\n"  /* comment3 */
printf(STR_OUTPUT_FORMAT_E1, "hello ", "macro, ", "yeah!");
我们得到的结果:编译错误。
通过gcc -E 选项我们看到,宏替换后的代码:
                              "%s"\
                              "%s\n"
int main() {
        printf("%s"\, "hello ", "macro, ", "yeah!");
}

由于没有续行符在注释前面,所以宏定义的后两行实际上并没有被包含在宏定义中,就像没有暂住证的人一样,被GCC这个"警察"逮个正着。

继续改进:
#define STR_OUTPUT_FORMAT_V3  "%s"   /* comment1 */ \
                              "%s"   /* comment2 */ \
                              "%s\n"  /* comment3 */
printf(STR_OUTPUT_FORMAT_V3, "hello ", "macro, ", "yeah!");
程序输出:hello macro, yeah!
显然预编译器忽略宏定义中的注释以及空格,STR_OUTPUT_FORMAT_V3就完全符合我的要求了。

当然,很多人不建议使用宏,特别是C++的Fans,宏也的确有很多弊端,这里也有替代方法:
const char *str_output_format = "%s"    /* comment1 */
                                 "%s"    /* comment2 */
                                 "%s\n"; /* comment3 */
printf(str_output_format, "hello ", "macro, ", "yeah!");
程序输出:hello macro, yeah!

用一个字符串变量代替格式宏,还可以避免上述由于在宏中做注释带来的一系列问题。

无线路由设置也'疯狂'

无线路由设置本来是件很简单的事情,但今晚却让我吃尽了苦头,这里暂且用'疯狂'来形容吧,也许有些不当。自从买了D-Link 624+A无线路由器之后,在家里上网就一直使用它了。这之前一直是使用我的工作笔电单机访问,今天不知怎么心血来潮,拿出我自己的'古董本本'(和今天的本本性能做比较,我的本本也算是古董级的了,有些夸张^_^),来一个双机访问,按理说:只要在无线路由器上配置一个DHCP服务器就可以了,可以个马虎的操作却让我花了近三个小时才搞定它。

我的本本03年购入,Acer的TravelMate系列。最近听说Acer已经坐上了全球PC第二把交椅,看来当初我的选择还不错。本子不自带无线网卡,早前买过一个TP-link WN210+的11M 802.11b的无线网卡,PCMCIA接口的,这回派上了用场。首先装驱动,还别说Windows自己在网上的确搜到了驱动,并安装了,不过这个驱动不支持WPA等安全模式,我的无线路由设置的是带有安全机制的访问方式;所以只能继续找专有驱动,在网上找了半天也没找到合适的,下了几个都不好用。突然想起自己的本子里好像有备份,果不其然啊,在我的Tools目录下有笔记本的全套驱动,真是"踏破铁鞋无觅处,得来全不费功夫"啊,安装一路顺利。

WPA安全方式已经可以支持了,但是依旧还是连不上我的无线,总是提示"网络受限或不可用",把D-link的设置看了一遍又一遍、改了一遍又一遍也是不好用。到网络上搜、到D-link官方站点找,试了多次依旧不行。通过D-Link的系统日志看到如下信息:"2008年3月7日, 星期五, x时xx分xx秒 Block xx-xx-xx-xx-xx-xx because deny all"。似乎是路由器故意要拦着我的本子。无奈下改变接入模式为OPEN的,随意接入。这回本子显示已经连接上了,并且获取了IP地址,网关和DNS设置都没有问题,本以为这样就ok了呢,但是依旧无法访问Internet。打开"控制台",ping一下网关,发现居然ping不通,路由器里面也没有相关对内部网络禁止ping的设置,系统日志依旧显示:"2008年3月7日, 星期五, x时xx分xx秒 Block xx-xx-xx-xx-xx-xx because deny all"。现在期指是疯狂,简直是绝望。

无意中,或者说思维混乱中,看到D-link配置界面的"进阶设定"-> "过滤器"的设置,点击"MAC地址过滤",发现我选择的策略居然是"只允许下述 MAC 地址之使用者存取网络 ",而下面的"MAC地址过滤表"中只有我这台IBM本子的MAC地址,问题找到了。思维回到若干天前,当刚刚买回路由器时,我胡乱设置这个过滤规则后,就忘记了,真没想到会给我今天带来这么大的麻烦。关闭MAC地址过滤后,我的老笔电终于可以Surfing the Internet了。

不过还有一个问题:当我将安全机制设回WPA-PSK模式后,我的本子又提示:"网络受限或不可用"了,我已经将无线profile删除重建了,但依然如此,不管了,凡能在非安全认证下可以访问已经是进步了,以后再慢慢摸索吧。

如发现本站页面被黑,比如:挂载广告、挖矿等恶意代码,请朋友们及时联系我。十分感谢! Go语言第一课 Go语言精进之路1 Go语言精进之路2 Go语言编程指南
商务合作请联系bigwhite.cn AT aliyun.com

欢迎使用邮件订阅我的博客

输入邮箱订阅本站,只要有新文章发布,就会第一时间发送邮件通知你哦!

这里是 Tony Bai的个人Blog,欢迎访问、订阅和留言! 订阅Feed请点击上面图片

如果您觉得这里的文章对您有帮助,请扫描上方二维码进行捐赠 ,加油后的Tony Bai将会为您呈现更多精彩的文章,谢谢!

如果您希望通过微信捐赠,请用微信客户端扫描下方赞赏码:

如果您希望通过比特币或以太币捐赠,可以扫描下方二维码:

比特币:

以太币:

如果您喜欢通过微信浏览本站内容,可以扫描下方二维码,订阅本站官方微信订阅号“iamtonybai”;点击二维码,可直达本人官方微博主页^_^:
本站Powered by Digital Ocean VPS。
选择Digital Ocean VPS主机,即可获得10美元现金充值,可 免费使用两个月哟! 著名主机提供商Linode 10$优惠码:linode10,在 这里注册即可免费获 得。阿里云推荐码: 1WFZ0V立享9折!


View Tony Bai's profile on LinkedIn
DigitalOcean Referral Badge

文章

评论

  • 正在加载...

分类

标签

归档



View My Stats