细说CC++中的宏(Macro)和宏替换.docVIP

  1. 1、本文档共4页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  5. 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  6. 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  7. 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  8. 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
细说CC中的宏(Macro)和宏替换

细说C/C++中的宏(Macro)和宏替换 宏(Macro),在C/C++中,是一个颇有争议的话题。在以前的老代码中,我们总是可以看到很多使用得很巧妙的宏,而在大多数的C++教材中,宏的使用都是不被推荐的,因为宏的使用比较容易产生BUG,这些BUG是由一些宏的边界效应(Side effect)所导致,而且这些BUG在调试的过程中都是很难发现的。到底该不该用宏?我的观点是,并不是因为它容易产生BUG就不用它,一定要学会如何用宏、何时用宏。很多时候,巧妙的使用宏,一方面可以减少代码量,一方面还可以提高代码效率。所以,我们现在要做的就是深入、全面了解宏相关的内容,只有充分的掌握了它,才会用好它! 1. 预处理命令(Preprocessor commands) (1) #define ?用来定义一个预处理宏,编译时直接替换 #define ?PI ?3.1415926 在代码中所有出现PI 的地方,都被替换为3.1415926,只是简单的替换,不做任何类型检查,因此,使用者必须确保类型的正确性。 (2)#undef 用来取消已经定义过的一个宏 #undef PI 如果在之前定义过PI,那么,在当前文件中从上面这行代码开始,以及包含上面这行代码所在文件的所有文件中,PI都不再代表3.1415926 (3)#include 用来引入一个要包含的文件 #include 在当前文件中引入stdio.h这个文件。 (4)#if… #endif , #if…#else…#endif, #if…#elif…#else…#endif, 几种条件宏定义的方式,只有在指定的条件成立时才引入该条件块中的预编译语句。这些条件宏定义语句,常和defined搭配在一起使用,但没有必要一定要使用defined。 #if ?defined(__DEBUG__) # ?define Msg(msg) printf(%s\n, msg) #else # ?define Msg(msg) #endif 上面的语句,只有在__DEBUG__宏定义的时候,Msg才会输出指定的字串信息。 另一种比较常的用法是,用条件语句来注释代码: #if 0 printf(This is commented\n); #endif 这样,在该条件语句块中的语句都将不会被执行。 (5)#ifdef…#endif, ?#ifdef…#else…#endif, #ifndef…#endif, #ifndef…#else…#endif. 这些条件宏定义的用法,和(4)中提到的条件宏与defined搭配在一起的用法差不多。 #ifdef _WIN32 # ?define STRNCASECMP _strnicmp #else # ?define STRNCASECMP strncasecmp #endif 上面的宏,定义了一个可跨平台的字符串比较函数,在windows平台上用_strnicmp()实现,在unix上用strncasecmp()实现。 (6)#,字符串替换,把跟在其后面的内容按字符串进行替换。 #define PUTS(s) printf(%s\n, #s) 使用上面的宏,PUTS(a)的替换结果就是 printf(%s\n, ?a) (7)#@,字符替换,把跟在其后面的内容按字符进行替换。 #define PUT(c) printf(%c\n, #@c) 使用上面的宏,PUT(a)的替换结果就是 printf(%c\n, c) (8)##,将两侧的两个token, 连接成为一个。 #define DEFINE_SETTER(name, type, member) \ void Set##name(const type amp; arg) \ { \ member = arg; \ } DEFINE_SETTER(Age, int, m_nAge),相当于定义了一个这样的函数: void SetAge(const int amp; arg) { m_nAge = arg; } 在成员变量很多的类中,为了保证比较好封装性,我们假定每个成员变量都是private的。这样我们就需要为每个成员实现对应的Setter和Getter,如果一个个去写,会有看上去很相似的函数,有很大的重复性的工作。此时,便可采用上面的宏的方式,一行搞定一个,看上去就代码比较简洁了。 (10)#error用来输出编译时的一些出错信息。 下面是一个名为Test.cpp的文件: #include ? #define SIZE 129 ? #if (SIZE % 128) != 0 #error SIZE must be a multiple of 128! #endif ?

您可能关注的文档

文档评论(0)

yan698698 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档