C语言程序设计 教学课件 ppt 作者 姚海军 全书 第9章

上传人:E**** 文档编号:89370589 上传时间:2019-05-24 格式:PPT 页数:39 大小:1.03MB
返回 下载 相关 举报
C语言程序设计 教学课件 ppt 作者 姚海军 全书 第9章_第1页
第1页 / 共39页
C语言程序设计 教学课件 ppt 作者 姚海军 全书 第9章_第2页
第2页 / 共39页
C语言程序设计 教学课件 ppt 作者 姚海军 全书 第9章_第3页
第3页 / 共39页
C语言程序设计 教学课件 ppt 作者 姚海军 全书 第9章_第4页
第4页 / 共39页
C语言程序设计 教学课件 ppt 作者 姚海军 全书 第9章_第5页
第5页 / 共39页
点击查看更多>>
资源描述

《C语言程序设计 教学课件 ppt 作者 姚海军 全书 第9章》由会员分享,可在线阅读,更多相关《C语言程序设计 教学课件 ppt 作者 姚海军 全书 第9章(39页珍藏版)》请在金锄头文库上搜索。

1、9.1 宏定义 9.2 文件包含 9.3 条件编译,9.1.1 编译预处理的概念 在前面各章中,已多次使用过以“#”号开头的预处理命令,如包含命令#include、宏定义命令 #define等。在源程序中这些命令都放在函数之外,而且一般都放在源文件的前面,它们称为预处理部分。,9.1 宏 定 义,所谓预处理,是指在进行编译的第一遍扫描(词法扫描和语法分析)之前所做的工作。预处理是语言的一个重要功能,它由预处理程序负责完成。当对一个源文件进行编译时,系统将自动引用预处理程序对源程序中的预处理部分做处理,处理完毕自动进入对源程序的编译。 语言提供了多种预处理功能,如宏定义、文件包含、条件编译等。合

2、理地使用预处理功能编写的程序便于阅读、修改、移植和调试,也有利于模块化程序设计。本章介绍常用的几种预处理功能。,9.1.2 宏定义 在语言源程序中允许用一个标识符来表示一个字符串,称为“宏”。被定义为“宏”的标识符称为“宏名”。在编译预处理时,对程序中所有出现的“宏名”都用宏定义中的字符串去代换,这称为“宏代换”或“宏展开”。 宏定义是由源程序中的宏定义命令完成的。宏代换是由预处理程序自动完成的。在语言中,“宏”分为有参数和无参数两种。下面分别讨论这两种“宏”的定义和调用。,1. 无参宏定义 无参宏的宏名后不带参数。其定义的一般格式为 #define 标识符 字符串 其中,define为宏定义

3、命令,标识符为宏名,字符串可以是常数、表达式、格式串等。 说明: 宏定义语句结尾没有分号。在标识符和字符串之间可以有任意个空格,字符串以回车换行结束。 #define TRUE 1 #define FALSE 0, 宏名定义后,可以作为其他宏名定义中的一部分。 #define FIRST 1 #define SECOND FIRST+5 #define THIRD FIRST+SECOND 如果在一个字符串中含有标识符,则不进行替换。 #define XYZ “this is a test” printf(“XYZ”); 执行后的结果是: XYZ 习惯上使用大写字母定义宏名。这样便于阅读程序。

4、因此最好将所有的 #define放到文件的开始或独立的文件中,而不是将它们分散到整个程序中。,2. 带参宏定义 C语言允许宏带有参数。在宏定义中的参数称为形式参数,在宏调用中的参数称为实际参数。对带参数的宏,在调用中,不需要宏展开,而要用实参去代换形参。 带参宏调用的一般格式为: #define 宏名(形参表) 字符串 其中,在字符串中含有各个形参。 带参宏调用的一般格式为 宏名(实参表);,例如: #define M(y) y*y+3*y k=M(5); 在宏调用时,用实参5去代替形参y,经预处理宏展开后的语句为: k=5*5+3*5 说明: 带参宏定义中,宏名和形参表之间不能有空格出现。,

5、 在带参宏定义中,形式参数不分配内存单元,因此不必作类型定义。而宏调用中的实参有具体的值,要用它们去代换形参,因此必须作类型说明。这是与函数中的情况不同的。在函数中,形参和实参是两个不同的量,各有自己的作用域,调用时要把实参值赋予形参,进行“值传递”。而在带参宏中,只是符号代换,不存在值传递。 在宏定义中的形参是标识符,而宏调用中的实参可以是表达式。,9.1.3 程序举例 【例9-1】 已知圆的半径,求圆面积和周长及球体积(使用不带参数的宏定义)。 程序清单如下: /-使用不带参数的宏定义- /- 求给定半径的圆周长、圆面积及构成球的体积- /-ex9_1.cpp- #include “std

6、io.h” #define PI 3.14159 /不带参数的宏定义,注意此处不带分号,图9-1 例9-1的输出结果,上例中,“#define PI 3.14159”的作用就是在本程序中用指定的标识符PI来代替“3.14159”这个字符串。在程序编译后,语句c=2*PI*r经宏展开为c=2*3.14159*5,其他语句类似。 【例9-2】 已知圆的半径,求圆面积和周长及球体积(使用带参数的宏定义)。 程序清单如下: /*-使用带参数的宏定义-*/ /*-求给定半径的圆周长、圆面积及构成球的体积-*/ /*-ex9_2.cpp-*/ #include “stdio.h“ #define PI 3

7、.14159,c=2*PI*a; area=S(a); volume=V(a); printf(“圆的周长C=%10.4fn圆的面积area=%10.4fn球的体积Volume=%10.4fn”,c,area,volume); 程序运行结果如图9-2所示。,图9-2 例9-2的输出结果,从结果看出,两次运行结果相同。在该例中,S(r)语句经编译后,area=S(r)这条语句宏展开为area=3.1415926*5*5,也就是说,S(a)中的实参a代替了宏定义语句中字符串PI*(r)*(r)中的形参r,得到PI*a*a。,9.2.1 文件包含的意义 在C语言开发程序时,可以把一些宏定义按照功能分

8、别存入不同的文件中,当我们需要使用某类宏定义时,就无需在程序中重新去定义,而只要把这些宏定义所在的文件包含在程序的开头就可以了。 所谓文件包含,是指在一个文件中,去包含另一个文件的全部内容。C语言通过 #include命令行来实现文件包含的功能。 #include命令行的格式如下: #include “文件名“ 或 #include ,9.2 文 件 包 含,在预编译时,预编译程序将用指定文件中的内容来替换此命令行。如果文件名用双引号括起来,系统先在源程序所在的目录内查找指定的包含文件,如果找不到,再按照系统指定的标准方式到有关目录中去寻找。如果文件名用尖括号括起来,将直接按照系统指定的标准方

9、式到有关目录中去寻找。 在程序设计中,文件包含是很有用的。一个大的程序可以分为多个模块,由多个程序员分别编程。有些公用的符号常量或宏定义等可单独组成一个文件,在其他文件的开头用包含命令包含该文件即可使用。这样,可避免在每个文件开头都去书写那些公用量,从而节省时间,并减少出错。,说明: #include命令行应书写在所用文件的开头,故有时也把包含文件称做“头文件”。头文件可以由用户指定,其后缀不一定用 .h。 包含文件中,一般包含有一些公用的 #include命令行、全局变量说明或对(库)函数的原型说明。例如stdio.h就是这样的头文件。 当包含文件修改后,对包含该文件的源程序必须重新进行编译

10、连接。 include命令只能包含一个头文件,在一个程序中,允许有任意多个 #include命令行。 在包含文件中还可以包含其他文件。,9.2.2 程序案例 【例9-3】 本程序说明用户如何定义自己的头文件并在程序中引用。 首先创建一个用户定义的名为usehead.h的头文件,并存放在当前目录下。其内容为: #define PRT printf #define PI 3.14159 再编写一个名为test.c的源文件,其内容为: #include “usehead.h” #include void main() ,float area; int ridius; PRT(“ridius=”);

11、scanf(“%d”, 运行程序: ridius=5 程序运行结果如图9-3所示。,图9-3 例9-3的输出结果,在上面的程序中,有一个用户自定义的头文件usehead.h,该头文件存放在当前目录下。文件中包括了两个宏定义,编译时系统会查询PTR和PI的出处,结果在usehead.h中找到,因此编译不会报错。如果没有在源文件中使用 #inlcude命令嵌入usehead.h,则编译时一定会报错,因为系统不能确定PRT和PI的出处。,9.3.1 条件编译的概念 一般情况下,源程序中所有的行都参加编译。但有时希望对其中一部分内容只在满足一定条件下才进行编译,也就是对一部分内容指定编译的条件,这就是

12、“条件编译”。 条件编译指令有以下三种形式: (1) # ifdef # else # endif,9.3 条 件 编 译,功能:当已被定义过(一般用#define指令定义),则对进行编译;否则,若有#else部分的话,编译。#else部分是可以缺省的。例如,在调试程序时,常常希望输出一些需要的信息,而在调试完成后不再输出这些信息,可在源程序中插入以下的条件编译段: # ifdef DEBUG printf(“x=%d,y=%d,z=%dn”,x,y,z); #endif 若在它前面有 #define DEBUG,则在程序运行时输出x、y、z的值,调试完成后需将这个 #define指令删除掉。

13、,(2) # ifndef #else #endif 功能:若未被定义,则编译;否则,若有 #else部分,编译。,(3) if #else endif 功能:若的值为非零,则对进行编译;否则,若有 #else部分,对进行编译。 注意:条件编译命令行不是语句,行尾不能有“;”号。,9.3.2 程序案例 【例9-4】 条件编译示例。 程序清单如下: /*-条件编译示例 -*/ /*- 求给定半径的圆周长、圆面积及构成球的体积-*/ /*-ex9_4.c-*/ #include “stdio.h“ #include “malloc.h“ #define NUM ok void main() ,图9

14、-4 例9-4条件编译1的输出结果,由于在程序的第21行插入了条件编译预处理命令,因此要根据NUM是否被定义过来决定编译哪一个printf语句,而在程序的第6行已对NUM作过宏定义,因此应对第一个printf语句作编译,运行结果是输出了学号和成绩。在程序的第6行宏定义中,定义NUM表示字符串OK,其实也可以为任何字符串,甚至不给出任何字符串,写为“#define NUM”也具有同样的意义。只有取消程序的第6行才会去编译第二个printf语句。其结果如图9-5所示。,图9-5 例9-4条件编译2的输出结果,【例9-5】 将字符串中的大写字母转换为小写字母。 程序清单如下: /-条件预处理的示例程序 -/-文件名ex9_5.c-#include #define LETTER 0 void main() char str20=“C Language“,c; int i; i=0; while(c=stri)!=0) ,图9-6 例9-5的输出结果,图9-7 例9-6的输出结果,

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 高等教育 > 大学课件

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号