细说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中就已经有了,但是考虑到兼容性并没有太多的...