第8章-编译预处理和动态存储分配.ppt
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_05.gif)
《第8章-编译预处理和动态存储分配.ppt》由会员分享,可在线阅读,更多相关《第8章-编译预处理和动态存储分配.ppt(20页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、第8章 编译预处理和动态存储分配 8.1 编译预处理8.2 宏定义 8.3 文件包含处理 8.4 动态存储分配 8.1 编译预处理 C语言允许在源程序中加入一些“预处理命令”(preprocessing directive),以改进程序设计环境,提高编程效率。这些预处理指令是由C标准建议的,但是它不是C语言本身的组成部分,不能用C编译系统直接对它们进行编译(因为编译程序不能识别它们)。所谓“编译预处理”就是在C编译程序对C源程序进行编译前,由编译预处理程序对这些编译预处理命令行进行处理的过程。在预处理阶段,预处理器把程序中的注释全部删除;对预处理指令进行处理,如把#include指令指定的头文
2、件(如stdio.h)的内容复制到#include指令处;对#define指令,进行指定的字符替换(如将程序中的符号常量用指定的字符串代替),同时删去预处理指令。8.1 编译预处理经过预处理后的程序不再包括预处理指令了,最后再由编译程序对预处理后的源程序进行实际的编译处理,得到可供执行的目标代码。C语言与其他高级语言的一个重要区别是可以使用预处理指令和具有预处理的功能。C语言提供的预处理功能常用的主要有以下3种:1、宏定义;2、文件包含;3、条件编译。这些预处理命令组成的预处理命令行必须在一行的开头以”#”号开始,每行的末尾不得用“;”号结束,以区别于C语句、定义和说明语句。这些命令行的语法与
3、C语言中其他部分的语法无关。根据需要,命令行可以出现在程序的任何一行的开始部位,其作用一直持续到源文件的末尾。8.2 宏定义 8.2.1 不带参数的宏定义8.2.2 带参数的宏定义 8.2.3 终止宏定义 8.2.1 不带参数的宏定义 1 不带参数的宏定义命令行形式格式:#define 宏名 替换文本或者:#define 宏名在define、宏名和宏替换文本之间用空格隔开。例如:#defineSIZE 100以上标识符SIZE称为“宏名”,是用户定义的标识符,因此,不得与程序中的其他名字相同。在编译时,在此命令行之后,预处理程序对源程序中的所有名为SIZE的标识符用100三个字符来替换,这个替
4、换过程称为“宏替换”。但要注意:不能认为“SIZE等于整数100”。#define命令行可以不包含“替换文本”,这种情况下仅说明标识符“被定义”。8.2.1 不带参数的宏定义2 替换文本中可以包含已定义过的宏名例8.1 计算圆面积。#include#define PI 3.1415926#define R 3.0#define S PI*R*R/*S的宏定义使用了前面的PI和R宏定义*/int main()printf(“圆的面积=%f”,S);return 0;运行结果:圆的面积=28.274333分析:该例中既有宏定义,又有宏定义的多重替换,这样求圆的面积,只需将宏名S进行展开后计算,输出
5、即可。8.2.1 不带参数的宏定义3 当宏定义在一行中写不下,需要在下一行继续时,只需在最后一个字符后紧接着加一个反斜线“”。例如:#defineLEAP_YEARyear%4=0&year%100!=0|year%400=0第一列如果在“”前或在下一行的开头留有许多空格,则在宏替换时也将加入这些空格。4 同一个宏名不能重复定义,除非两个宏定义命令行完全一致。5 替换文本不能替换双引号中与宏名相同的字符串。例8.2 宏名相同的字符串不能替换。#defineBOOK“The Red and The Black”int main()printf(“%sn”,”BOOK”);return 0;运行结
6、果:BOOK8.2.1 不带参数的宏定义6 替换文本并不替换用户标识符中的成分。例如,宏名YES,不会替换标识符YESORNO中的YES。7 用作宏名的标识符通常用大写字母表示,这并不是语法规定,只是一种习惯,以便与程序中的其他标识符相区别。8 在C程序中,宏定义的定义位置一般写在程序的开头。返回8.2.2 带参数的宏定义 1 带参数的宏定义命令行形式如下:格式:#define宏名(形参表)替换文本如果定义带参数的宏,在对源程序进行预处理时,将程序中出现宏名的地方均用替换文本替换,并用实参代替替换文本中的形参。例8.3 编写程序,使用带参数的宏定义。#include#define MAX(a,
7、b)ab?a:b/*定义带参数的宏 MAX*/#define SQR(c)c*c/*定义带参数的宏 SQR*/int main()int x=3,y=4;x=MAX(x,y);y=SQR(x);printf(“x=%d,y=%dn”,x,y);return 0;运行结果:x=4,y=16对于带参的宏定义有以下问题需要说明:2.带参宏定义中,宏名和形参表之间不能有空格出现。例如把:#define MAX(a,b)(ab)?a:b写为:#define MAX (a,b)(ab)?a:b将被认为是无参宏定义,宏名MAX代表字符串(a,b)(ab)?a:b。宏展开时,宏调用语句:max=MAX(x,y
8、);将变为:max=(a,b)(ab)?a:b(x,y);这显然是错误的。8.2.2 带参数的宏定义3.在带参宏定义中,形式参数不分配内存单元,因此不必作类型定义。而宏调用中的实参有具体的值。要用它们去代换形参,因此必须作类型说明。这是与函数中的情况不同的。在函数中,形参和实参是两个不同的量,各有自己的作用域,调用时要把实参值赋予形参,进行“值传递”。而在带参宏中,只是符号代换,不存在值传递的问题。4.在宏定义中的形参是标识符,而宏调用中的实参可以是表达式。例8.4 宏调用实参为表达式。#define SQ(y)(y)*(y)main()int a,sq;printf(input a numb
9、er:);scanf(%d,&a);sq=SQ(a+1);printf(sq=%dn,sq);运行结果:input a number:3sq=16分析:上例中第一行为宏定义,形参为y。程序第七行宏调用中实参为a+1,是一个表达式,在宏展开时,用a+1代换y,再用(y)*(y)代换SQ,得到如下语句:sq=(a+1)*(a+1);这与函数的调用是不同的,函数调用时要把实参表达式的值求出来再赋予形参。而宏代换中对实参表达式不作计算直接地照原样代换。8.2.2 带参数的宏定义5.在宏定义中,字符串内的形参通常要用括号括起来以避免出错。在上例中的宏定义中(y)*(y)表达式的y都用括号括起来,因此结果
10、是正确的。如果去掉括号,把程序改为以下形式:例8.5#define SQ(y)y*ymain()int a,sq;printf(input a number:);scanf(%d,&a);sq=SQ(a+1);printf(sq=%dn,sq);运行结果:input a number:3sq=7分析:同样输入3,但结果却是不一样的。问题在哪里呢?这是由于代换只作符号代换而不作其它处理而造成的。宏代换后将得到以下语句:sq=a+1*a+1;由于a为3故sq的值为7。这显然与题意相违,因此参数两边的括号是不能少的。即使在参数两边加括号还是不够的,请看下面程序:8.2.2 带参数的宏定义例8.6#d
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译 预处理 动态 存储 分配
![提示](https://www.taowenge.com/images/bang_tan.gif)
限制150内