今天我要给大家讲一个我很不希望大家会的功能,但是这项能力缺失的话又确实不能真正成为一个合格的 C/C++ 语言开发者。这个功能就是 C 语言里的宏。我们先来看一段比较新的 VC 生成的默认项目中的代码:
可以看到默认生成的主函数居然不是 main(),而是一个叫 _tmain() 的东西!这和我们在学校里学到的完全不同啊。这样让初学都胆寒的代码其实要这样看,我们在它的函数声明上点击右键,然后选择跳转到它的定义,那么就会看到以下的代码:
define _tmain wmaindefine _tmain main
根据不同的项目配置,定义有可能跳到第一句话也可能跳到第二句话。这 是因为 vc 能编译出4种类型的程序(也许现在能更多种了吧,但至少这4种都还有的)那就是传统 C 语言入口版本和 Windows 入口版本 … 等等,这不是两种吗?问题在于 vc 不知道从什么时候开始支持用宏定义来实现不同于传统字符串的 unicode 版本,所以前面两个版本又各自有传统字符串版本和 unicode 字符串两种版本。在 VC 中这两种字符串的表示代码是不一样的,但 vc 又希望它的用户可以不改动代码就能编译出两种版本的程序,所以它推荐的字符串定义是这样的:
_T(“string”)
这种无语的做法还涉及到很多代码,我就不一一的列举了。要说的是这种做法已经落后了!我知道很多 VC 粉不愿意同意,但是事实就是如此。这种为了支持多语言需要改变字符串写法的做法我真的很不以为然后,如果我的程序想支持传统字符串又想支持 unicode16 又想支持 utf8 呢?这个宏完全是没有办法解决的。另外要稍微提一下的是 utf8 和我们常说的 unicode 的处理是很不一样的,我们常说的 unicode 其实是 unicode16 … 要说下去就太多了。实际业界对字符集的处理主要是用 iconv 库函数来实现的。不过我们这篇文章并不是专门说字符集的,只是用字符集的处理方式来做示例告诉大家现在的环境中对宏的滥用程度。
宏定义在 C/C++ 里还有一个常用的使用地方就是算式经常用宏来实现而不是函数,很多使用起来象函数的 “函数” 其实是宏,比如 max 这样的操作。支持都们一般会说这样做是因为快!我想说的是那是因为写这种程序的人没那个能力优化性能,当今世界这么多的语言只有 C/C++ 把宏替换当做一种程序优化的方式,其实真正要优化的是算法而不是这种替换代码代替函数调用的方式。再怎么换一个传统的搜索代码也比不上一个简单的 hash 搜索,两者相差千万倍的性能,这根本不是宏替换就能解决的。所以除了 C/C++ 没有什么语言会再这样做了。
宏替换还有一个非常严重的问题,那就是兼容性,而且因为宏无法调试一旦有某些隐晦的问题,你想找问题简直难于登天。我觉得一个合格的 C++ 项目经理第一件事应该就是禁用宏的滥用。我以前在移植代码到 symbian 中时就出过这种问题(科普下这个是以前 nokia 的手机运行环境,想当年 nokia 可是 … 咳咳,算了)。
所以,我最后总结一下给初学者们的忠告:宏替换的代码是要学会看懂的,但项目里不要用。除非您的项目是需要在 windows 和 linux 中同时兼容,那一般实现的手段只能是宏定义判断了。
估计大多数初学者都没看懂,不过大家记住这个原则,贯彻到以后的学习过程中去就可以了。好了,这就是我们今天要说的内容。
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,请使用WINRAR解压,如遇到无法解压的请联系管理员!
8. 精力有限,不少源码未能详细测试(解密),不能分辨部分源码是病毒还是误报,所以没有进行任何修改,大家使用前请进行甄别
丞旭猿论坛
暂无评论内容