关键词不能为空

当前您在: 主页 > 英语 >

sackC++ 宏定义说明(详解)

作者:高考题库网
来源:https://www.bjmy2z.cn/gaokao
2021-01-28 16:48
tags:

sack-tvt

2021年1月28日发(作者:blame是什么意思)


宏定义有


无参数宏定义



带参数宏定义


两种。



无参数的宏定义的一般形式为



# define


标识符



字符序列



其中


# define


之后的标识符称 为宏定义名


(


简称宏名


)


,要求宏名与字符序列之间用空格符分


隔。


这种宏定 义要求编译预处理程序将源程序中随后所有的定名的出现


(


注释 与字符串常量中


的除外


)


均用字符序列 替换之。前面经常使用的定义符号常量是宏定义的最简单应用。如有:



# define TRUE 1


# define FALSE 0


则在定义它们的源程序文件中,凡定义之后出现的 单词


TRUE


将用


1

< br>替代之;出现单词


FALSE


将用


0


替代之。




在宏定义的#之前可以有若干个空格、


制表符,


但不允许有其它字符。


宏定义在源程


序中单独另起一行,换行 符是宏定义的结束标志。如果一个宏定义太长,一行不



够时,


可采


用续行的方法。续行是在键人回车符之前先键入符号



。注意回车要紧接在符号


之后,


中间不能插入其它符号。




宏定义的有效范围称为宏定义名的辖域,


辖域从宏定义的定义结 束处开始到其所在的


源程序文件末尾。宏定义名的辖域不受分程序结构的影响。


可以用预处理命令


#undef


终止宏


定义名的辖域。




在新的宏定义中,可以使用前面已定义的宏名。例如,



# define R 2.5


# define PI 3.1415926


# define Circle 2*PI*R


# define Area PI* R * R


程序中的


Ci rcle


被展开为


2*3.1415926* 2.5



Area


被展开为


3.1415926*2.5*2.5





如有必要,宏名可被重复定义。被重复定义后,宏名 原先的意义被新意义所代替。



< br>通常,无参数的宏定义多用于定义常量。程序中统一用宏名表示常量值,便于程序前


后统一,不易出错,也便于修改,能提高程序的可读性和可移植性。特别是给数组元素个数

一个宏定义,并用宏名定义数组元素个数能部分弥补数组元素个数固定的不足。




注意:


预处理程序在处理 宏定义时



只作字符序列的替换工作,


不作任何语法的检查。


如果宏定义不当,错误要到预处理之后的编译阶段才能发现。宏定 义以换行结束,不需要分


号等符号作分隔符。如有以下定定义:



# define PI 3.1415926




原希望用


PI


求圆的周长的语句



c



2*PI*r




经宏展开后,变成



c



2*3.1415926* r




这就不能达到希望的要求。





带参数宏定义进一步扩充了无参数宏定义的能力,在字符序列 替换同时还能进行参数替


换。带参数定定义的一般形式为



# define


标识符


(< /p>


参数表


)


字符序列



其中参数表中的参数之间用逗号分隔,


字符序列中应包含参 数表中的参数。


在定义带参数的


宏时,


宏名标识符与左圆括号之间不允许有空白符,


应紧接在一起,


否 则变成了无参数的宏


定义。


如有宏定义:



# define MAX(A



B) ((A) > (B)?(A):(B))


则代码


y



MAX( p



q



u+v)


将被替换成


y


< p>
((p



q) >(u



v)?(p



q):(u



v)





程序中的宏调用是这样被替换展开的,


分别用宏调用中的实在参数字符序列


(



p



q


和< /p>


u



V)


替换 宏定义字符序列中对应所有出现的形式参数


(


如用


p



q


替代所有形式参



A




u



V


替代所有形式参 数


B)



而宏定义字符序列中的不是形 式参数的其它字



符则保


留。这样形成 的字符序列,即为宏调用的展开替换结果。


宏调用提供的实在参数个数必须与

< p>
宏定义中的形式参数个数相同。




注意:宏调用与函数调用的区别。函数调用在程序运行时实行,而宏展开是在编译


的预处理阶段进行;函数调用占用程序运行时间,宏调用只占编译时间;函数调用



对实参


有类型要求,


而宏 调用实在参数与宏定义形式参数之间没有类型的概念,


只有字符序列的对


应关系。函数调用可返回一个值,宏调用获得希望的


C


代码。另



外,函数调用时,实参表


达 式分别独立求值在前,执行函数体在后。宏调用是实在参数字符序列替换形式参数。替换


后,实在参数字符序列就与相邻的字符自然连



接,实在参数的 独立性就不一定依旧存在。


如下面的宏定义:



# define SQR(x) x*x


希望实现表达式的平方计算。对于宏调用



P



SQR(y)

< p>
能得到希望的宏展开


p



y*y


。但对于宏调用


q


< p>
SQR(u



v)


得到的 宏展开是


q



u



V*u



V



显然,后者的展开结果不是程序设计者所希望的。为能保持实在参数替换后的独立性 ,应在


宏定义中给形式参数加上括号。进一步,为了保证宏调用的独立性,作为算式的宏 定义也应


加括



号。如


SQR


宏定义改写成:



# define SQR((x)*(x))


才是正确的宏定义。



< /p>


对于简短的表达式计算函数,或为了提高程序的执行效率、避免函数调用时的分配


存储单元、保留现场、参数值传递、释放存储单元等工作。可将函数定义改写成宏定义。所


以合理使用宏定义,可以使程序更简洁。




使用一些宏跟踪调试




A N S I


标准


说明了五个预定义 的宏名。它们是:



_ L I N E _ (

< p>
两个下划线


)


,对应


%d


_ F I L E _


对应


%s


_ D A T E _


对应


%s


_ T I M E _


对应


%s


_ S T D C _


如果编译不是标准的


,


则可能仅支持以 上宏名中的几个


,


或根本不支持。记住编译程序



也许还提供其它预定义的宏名。



_ L I N E _



_ F I L E _


宏指令在有关


# l i n e

< br>的部分中已讨论


,


这里讨论其余的宏名。



_ D AT E _


宏指令含有形式为月


/



/


年的串


,


表示源文件被翻译到代码时的日期。



源代码翻译到目标代码的时间作为串包含在


_ T I M E _


中。串形式为时:分:秒。



如果 实现是标准的


,


则宏


_ S T D C _


含有十进制常量


1


。如果它含有 任何其它数


,


则实现是



非标准的。



可以定义宏

< p>
,


例如


:


当定义了< /p>


_DEBUG,


输出数据信息和所在文件所在行

< br>


#ifdef _DEBUG


#define DEBUGMSG(msg,date) printf(msg);printf(“%d%d%s”,date,_LINE_,_FILE_)



#else


#define DEBUGMSG(msg,date)


#endif


20,


宏定义防止使用是错误



用小括号包含。




例如:


#define ADD(a,b)



a+b



sack-tvt


sack-tvt


sack-tvt


sack-tvt


sack-tvt


sack-tvt


sack-tvt


sack-tvt



本文更新与2021-01-28 16:48,由作者提供,不代表本网站立场,转载请注明出处:https://www.bjmy2z.cn/gaokao/580569.html

C++ 宏定义说明(详解)的相关文章