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

细说C/C++中的宏(Macro)和宏替换宏(Macro),在C/C++中,是一个颇有争议的话题。在以前的老代码中,我们总是可以看到很多使用得很巧妙的宏,而在大多数的C++教材中,宏的使用都是不被推荐的,因为宏的使用比较容易产生BUG,这些BUG是由一些宏的边界效应(Sideeffect)所导致,而且这些BUG在调试的过程中都是很难发现的。到底该不该用宏?我的观点是,并不是因为它容易产生BUG就不用它,一定要学会如何用宏、何时用宏。很多时候,巧妙的使用宏,一方面可以减少代码量,一方面还可以提高代码效率。所以,我们现在要做的就是深入、全面了解宏相关的内容,只有充分的掌握了它,才会用好它!1.预处理命令(Preprocessorcommands)(1)#define用来定义一个预处理宏,编译时直接替换#definePI3.1415926在代码中所有出现PI的地方,都被替换为3.1415926,只是简单的替换,不做任何类型检查,因此,使用者必须确保类型的正确性。(2)#undef用来取消已经定义过的一个宏#undefPI如果在之前定义过PI,那么,在当前文件中从上面这行代码开始,以及包含上面这行代码所在文件的所有文件中,PI都不再代表3.1415926(3)#include用来引入一个要包含的文件#include在当前文件中引入stdio.h这个文件。(4)#if…#endif,#if…#else…#endif,#if…#elif…#else…#endif,几种条件宏定义的方式,只有在指定的条件成立时才引入该条件块中的预编译语句。这些条件宏定义语句,常和defined搭配在一起使用,但没有必要一定要使用defined。#ifdefined(__DEBUG__)#defineMsg(msg)printf("%s\n",msg)#else#defineMsg(msg)#endif上面的语句,只有在__DEBUG__宏定义的时候,Msg才会输出指定的字串信息。另一种比较常的用法是,用条件语句来注释代码:#if0printf("Thisiscommented\n");#endif这样,在该条件语句块中的语句都将不会被执行。(5)#ifdef…#endif,#ifdef…#else…#endif,#ifndef…#endif,#ifndef…#else…#endif.这些条件宏定义的用法,和(4)中提到的条件宏与defined搭配在一起的用法差不多。#ifdef_WIN32#defineSTRNCASECMP_strnicmp#else#defineSTRNCASECMPstrncasecmp#endif上面的宏,定义了一个可跨平台的字符串比较函数,在windows平台上用_strnicmp()实现,在unix上用strncasecmp()实现。(6)#,字符串替换,把跟在其后面的内容按字符串进行替换。#definePUTS(s)printf("%s\n",#s)使用上面的宏,PUTS(a)的替换结果就是printf("%s\n","a")(7)#@,字符替换,把跟在其后面的内容按字符进行替换。#definePUT(c)printf("%c\n",#@c)使用上面的宏,PUT(a)的替换结果就是printf("%c\n",'c')(8)##,将两侧的两个token,连接成为一个。#defineDEFINE_SETTER(name,type,member)\voidSet##name(consttypearg)\{\member=arg;\}DEFINE_SETTER(Age,int,m_nAge),相当于定义了一个这样的函数:voidSetAge(constintarg){m_nAge=arg;}在成员变量很多的类中,为了保证比较好封装性,我们假定每个成员变量都是private的。这样我们就需要为每个成员实现对应的Setter和Getter,如果一个个去写,会有看上去很相似的函数,有很大的重复性的工作。此时,便可采用上面的宏的方式,一行搞定一个,看上去就代码比较简洁了。(10)#error用来输出编译时的一些出错信息。下面是一个名为Test.cpp的文件:#include#defineSIZE129#if(SIZE%128)!=0#error"SIZEmustbeamultipleof128!"#endifintmain(){}对Test.cpp用g++-cTest.cpp命令编译,会得到如下错误信息:Test.cpp:6:2:error:#error“SIZEmustbeamultipleof128!”(11)#line用来暗示编译器,当前代码的这一行是由用户写的代码中某个文件中的某一行生成的。(12)#pragma用来给编译器指定与实现相关的一些信息,在所有的预处理命令中,#pragma是最为复杂的,下面对其进行比较详细的说明:#pragma的使得语法为:#pragmapara,其中para为其参数,下面介绍一些常用的参数。A.#pragmamessage(“text”)在编译信息输出窗口中输出text信息B.#pragmaonce只要在头文件的最开始加入这条指令就能够保证头文件被编译一次,这条指令实际上在VC6中就已经有了,但是考虑到兼容性并没有太多的...

1、当您付费下载文档后,您只拥有了使用权限,并不意味着购买了版权,文档只能用于自身使用,不得用于其他商业用途(如 [转卖]进行直接盈利或[编辑后售卖]进行间接盈利)。
2、本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供参考,付费前请自行鉴别。
3、如文档内容存在侵犯商业秘密、侵犯著作权等,请点击“举报”。

常见问题具体如下:

1、问:已经付过费的文档可以多次下载吗?

      答:可以。登陆您已经付过费的账号,付过费的文档可以免费进行多次下载。

2、问:已经付过费的文档不知下载到什么地方去了?

     答:电脑端-浏览器下载列表里可以找到;手机端-文件管理或下载里可以找到。

            如以上两种方式都没有找到,请提供您的交易单号或截图及接收文档的邮箱等有效信息,发送到客服邮箱,客服经核实后,会将您已经付过费的文档即时发到您邮箱。

注:微信交易号是以“420000”开头的28位数字;

       支付宝交易号是以“2024XXXX”交易日期开头的28位数字。

客服邮箱:

biganzikefu@outlook.com

所有的文档都被视为“模板”,用于写作参考,下载前须认真查看,确认无误后再购买;

文档大部份都是可以预览的,笔杆子文库无法对文档的真实性、完整性、准确性以及专业性等问题提供审核和保证,请慎重购买;

文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为依据;

如果您还有什么不清楚的或需要我们协助,可以联系客服邮箱:

biganzikefu@outlook.com

常见问题具体如下:

1、问:已经付过费的文档可以多次下载吗?

      答:可以。登陆您已经付过费的账号,付过费的文档可以免费进行多次下载。

2、问:已经付过费的文档不知下载到什么地方去了?

     答:电脑端-浏览器下载列表里可以找到;手机端-文件管理或下载里可以找到。

            如以上两种方式都没有找到,请提供您的交易单号或截图及接收文档的邮箱等有效信息,发送到客服邮箱,客服经核实后,会将您已经付过费的文档即时发到您邮箱。

注:微信交易号是以“420000”开头的28位数字;

       支付宝交易号是以“2024XXXX”交易日期开头的28位数字。

笔杆子文秘
机构认证
内容提供者

为您提供优质文档,供您参考!

确认删除?