- 1、本文档共8页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
C语言知识第10章-王厚财
第十章 编译预处理与动态存储分配
10.1 编译预处理
C语言提供编译预处理的功能,这是C语言编译系统的一个组成部分。编译预处理是指对C语言编写的程序进行编译之前,先对程序中的一些特殊的命令进行预先的处理,然后将预处理后的结果和源程序一起再进行通常的编译处理,得到目标代码。
在C语言中,这些特殊的命令都是以“#”开头的,像前面学习的# define、#include等命令都是预编译处理命令;并且每行的末尾不能加“;”,以区别于C语句。C语句每行的末尾必须加“;”,而预编译处理命令不能加“;”。这是命令与语句的区别。
C语言提供的预编译处理命令主要有以下三种:
宏替换
文件包含
条件编译
下面我们对1和2这两种预编译命令进行讲解。
10.1.1宏替换
1.不带参数的宏替换
用一个指定的标识符(宏名)来代表一串字符,定义形式为:
#define 宏名 替换文本
在define与宏名之间、宏名与替换文本之间用一个或多个空格隔开。例如:
#define PI 3.1415926
这也就是前面介绍过的符号常量的定义。
在编译预处理时,把程序中在该命令之后的所有的PI标识符都用3.1415926代替,这个替换过程称为“宏替换”或“宏展开”。
说明:
(1)#define命令行后可以省略替换文本,这种情况下仅说明标识符被定义。例如:
#define ADD
(2)替换文本中可以包含已定义过的宏名,例如:
#define R 3
#define PI 3.1415926
#define S PI*R*R
(3)宏名一般习惯上采用大写字母,也可以使用小写字母,并且在行尾不能加“;”。
(4)同一个宏名不能重复定义,除非两个宏定义命令行完全一致。
(5)替换文本不能替换双引号中与宏名相同的字符串,也不能替换用户标识符中与宏名相同的部分字符。
(6)宏定义在一行写不下时,可以与C语句一样,在行尾加续行符“\”,在下一行开始接着继续写。但注意在“\”的前后都不能有空格,否则空格也作为替换文本的一部分。
(7)C语言中,宏定义的位置一般放在程序的开头。宏名的有效范围也从宏的定义开始到本文件结束为止,也可以使用#undef命令终止宏的作用范围。命令的使用形式为:
# undef 宏名
替换文本为表达式,并且宏名又参与了表达式的运算,则替换文本一般用()括起来,来保证运算的顺序。例如:
# define PI 3.1415926
# define ADDPI (PI+2)
# define TWO_ADDPI 2*ADDPI
若在定义ADDPI时,其替换文本中不加(),则TWO_ADDPI的替换文本的值与加()是不相同。
2.带参数的宏替换
带参数的宏定义命令的定义形式为:
# define 宏名(形参表) 替换文本
一般在替换文本中含有在()中指定的参数。如:
#define S(a,b) a*b
……
area=S(3,2);/*引用带参数的宏*/
在上面的例子中定义了带参数的宏S,S是宏名,它含有两个参数a和b。在引用宏S时,也要有两个参数,在进行宏的展开时,不仅用替换文本代替宏名,还要用实参替换形参。因此在例题中,不仅用a*b替换S(3,2),并且用3替换a,用2替换b。经过宏展开后,赋值语句为:
area=3*2;
(1)参数的宏在定义时,宏名与后面的“(”不能有空格,各形参之间用“,”分开。若宏名与“(”之间有空格,则将空格后的所有的字符都认为是替换文本,带参数的宏,被处理成不带参数的宏。
如:#define S (r) PI*r*r
area=S(3.0); = area=(r) PI*r*r(3.0);
(2)引用带参数的宏与函数的调用类似,各实参之间用“,”分开,并且实参的个数与形参个数要一致。在编译预处理时,用实参替换替换文本中对应的形参。
(3)若“替换文本”是表达式,则替换文本与形参最好用“()”括起来。否则在宏展开时,计算的顺序容易发生改变。
#define S(a,b) a*b
程序中area=S(a+b,c+d);=area=a+b*c+d;明显和我们的意图不同。
假如:宏定义的字符串中的形参用()括号括起来,即:
#define S(a,b) (a)*(b)
此时程序中:
area=S(a+b,c+d);=area=(a+b)*(c+d);符合我们的意图。
(4)宏替换时,不能用实参替换双引号中的形参。
(5)带参数的宏替换与函数的调用有相似之处,但在函数调用时,先求出实参表达式的值,然后将值传递给形参;而带参数的宏替换只是简单的用实参替换形参,实参不先进行计算。
(6)函数调用是在程序运行时处理的,并为形参分配临时的存储单元,函数
文档评论(0)