C语言程序设计 教学课件 ppt 作者 姜海涛 《C语言程序设计》第八章

上传人:E**** 文档编号:89188030 上传时间:2019-05-20 格式:PPT 页数:30 大小:1.49MB
返回 下载 相关 举报
C语言程序设计 教学课件 ppt 作者 姜海涛 《C语言程序设计》第八章_第1页
第1页 / 共30页
C语言程序设计 教学课件 ppt 作者 姜海涛 《C语言程序设计》第八章_第2页
第2页 / 共30页
C语言程序设计 教学课件 ppt 作者 姜海涛 《C语言程序设计》第八章_第3页
第3页 / 共30页
C语言程序设计 教学课件 ppt 作者 姜海涛 《C语言程序设计》第八章_第4页
第4页 / 共30页
C语言程序设计 教学课件 ppt 作者 姜海涛 《C语言程序设计》第八章_第5页
第5页 / 共30页
点击查看更多>>
资源描述

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

1、第八章 预处理指令,主要内容,宏替换,1,文件包含,2,本章要点及学习目标,本章要点 宏替换指令 文件包含指令 学习目标 理解预处理的含义 掌握简单宏替换和带参数宏替换的规则 掌握宏替换指令和文件包含指令的使用方法,预处理指令,以字符“#”开头,后面跟不同的指令名,如#include、#define 预处理指令不能直接进行编译。在编译之前必须对这些指令提前进行处理,即“预处理”。 C语言中常用的预处理指令包括以下三类:宏替换、文件包含、条件编译。,8.1 宏替换,8.1.1 简单宏替换 【例】编程实现求圆的周长、面积与球的体积。,/*程序8-1*/ #include void main( )

2、float radius; float c, s, v; printf(“请输入半径:n”); scanf(“%f”, ,8.1 宏替换(续),在上述程序中,存在着如下问题: (1)常量3.1415926在程序中出现了三次,由于其包含字符较多,给程序的编写带来一定的麻烦; (2)如果在程序编写中将某位置的3.1415926输入错误,则对应的部分结果将出现错误,从而造成结果的不一致。,8.1 宏替换(续),使用宏替换可以解决上面的问题,将程序8-1修改如下:,/*程序8-2*/ #include #define PI 3.1415926 void main( ) float radius; fl

3、oat c, s, v; printf(“请输入半径:n”); scanf(“%f”, ,8.1 宏替换(续),宏替换即用一个指定的标识符来代表一个替换序列,其一般形式为: #define 标识符 替换序列 其中标识符被称为宏名,替换序列其实是一个字符序列(可以包含标识符、关键字、常数、字符串常量、运算符、标点符号等)。,8.1 宏替换(续),宏替换指令在程序编译前被预处理器处理,此时,预处理器将程序代码作为字符序列来对待,不考虑代码的含义。 预处理器遇到一个宏替换指令时,会登记“标识符”代表“替换序列”的信息,然后将后面的程序代码中出现的所有PI替换为3.1415926。替换完成后得到的程序

4、代码和程序8-1相同。 真正被编译执行的是替换后的代码。,8.1.2 带参数的宏替换,其一般形式为: #define 标识符(形式参数列表) 替换序列 其中形式参数列表中可以包含若干个参数(参数之间用逗号分隔),每个参数均为一个标识符。这些参数可以在替换序列中出现多次。 在程序代码中,调用带参数宏替换的方式为: 宏名(实际参数列表) 其中每个实际参数均是一个字符序列(可以包含标识符、关键字、常数、字符串常量、运算符、标点符号等),实际参数的个数应和形式参数的个数相同。,8.1.2 带参数的宏替换(续),预处理器遇到带参数的宏替换时,将登记相关的信息以便以后使用。在后面的程序代码中如果出现了宏调

5、用,宏调用将被替换序列所取代,同时用每个实际参数替换对应的形式参数。,/*程序8-3*/ #include #define PI 3.1415926 #define C(r) 2*PI*r #define S(r) PI*r*r #define V(r) 4*PI*r*r*r/3 void main( ) float radius; float c, s, v; printf(“请输入半径:n”); scanf(“%f”, ,8.1.2 带参数的宏替换(续),程序8-3替换后得到如下程序,#include void main( ) float radius; float c, s, v; pr

6、intf(“请输入半径:n”); scanf(“%f”, ,使用宏替换指令需要注意,(1)宏替换不是语句,因此指令的最后通常不加分号,错误的添加分号(分号将被作为替换序列的一部分)可能会导致替换后得到的程序代码出现语法错误。如: #define PI 3.1425926; s = PI * r * r; 语句经预处理后会替换为: s = 3.1415926; * r * r 编译时会提示语法错误!,使用宏替换指令需要注意(续),(2)不论是带参数的宏还是不带参数的宏,在处理时预处理器只是进行字符序列的替换,不会执行其中的运算。例: #include #define square(n) n*n

7、main() int a = 2; printf(“%d”, square(a+1); 进行替换后,square(a+1)会替换为a+1*a+1,而非(a+1)*(a+1)。这是由替换的规则所决定的。对于上述例子,我们可以做如下改进: #define square(n) (n)*(n),使用宏替换指令需要注意(续),【例8-1】有如下程序 /*程序8-4*/ #define N 2 #define M N+1 #define NUM 2*M+1 void main( ) int i; for(i=1;i=NUM;i+) printf(“%dn”,i); 请思考,该程序中for语句的循环体执行的

8、次数是多少?,使用宏替换指令需要注意(续),(3)定义带参数的宏时,宏名和左括号之间不能有空格,否则被认为是无参数的宏,“(形式参数列表)”将被作为替换序列的一部分。 #define square (n) n*n void main( ) int a = 2; printf(“%d”, square(a+1); 预处理后上述程序代码会替换为: void main( ) int a = 2; printf(“%d”, (n) n*n(a+1); 编译时编译器会提示错误。,使用宏替换指令需要注意(续),(4)类似于全局变量,宏替换的作用范围是从它的定义开始直到源文件结束,但我们可以通过#undef

9、预处理指令提前终止相应宏的作用范围。如 #define PI 3.1415926 void main( ) #undef PI void func() 则在func函数内不能使用PI宏定义,因为func函数不在PI的作用范围内。,使用宏替换指令需要注意(续),(5)对于程序中用双引号括起来的字符串内的字符序列,即使同宏名相同也不被替换,例如: #define PI 3.1415926 void main( ) . printf(“PI=%fn”, PI); printf格式字符串内的PI不会被替换,而后面的PI将会被替换。,使用宏替换指令需要注意(续),(6)带参数的宏替换从形式上来看与函数类

10、似,但其实现方式与函数有本质的不同,二者的区别主要体现在以下几个方面: a从形式上来看,函数定义中形参必须指定类型,如果实参的类型与形参不一致,将进行类型转换;而带参数的宏替换的形式参数不须指定类型,因为其参数没有类型,只是一个标识符,将来用实际参数直接代替即可。 b从执行时间上来看,函数经过编译、链接后在程序运行过程中被调用执行;而带参数的宏替换在编译之前就被替换。,使用宏替换指令需要注意(续),c从执行方式上来看,函数的执行是在程序运行时处理的,需要分配临时的内存单元,并涉及到运行环境的保存与恢复,因此将耗费额外的内存资源与执行时间;而带参数的宏替换的替换操作是在编译前进行的,在替换时并不

11、分配内存单元,不进行值的传递处理,也没有“返回值”的概念。,8.2 文件包含,文件包含指令的一般格式为: #include 或 #include “文件名” 两种格式的区别在于: 第一种格式定义时,预处理器在C语言编译系统指定的标准目录中查找指定名称的文件。 第二种格式定义时,预处理器首先在当前目录中寻找指定名称的文件,如果没找到,再到系统指定的标准目录中查找。,8.2 文件包含(续),一个源程序文件的开头通常都会放置多个#include指令,它们通常用来包含系统头文件,比如。在系统头文件中包含了一些符号常量、外部变量、数据类型的定义和大量库函数的声明。通过包含系统头文件,我们就可以在源程序中

12、直接使用这些常量、数据类型或库函数了。,8.2 文件包含(续),在进行预处理时,所有的#include指令都将被替换为由文件名指定的文件的内容,如下图所示:,使用文件包含指令需要注意,(1)一个#include指令只能包含一个文件,要包含n个文件需要n个#include指令 (2)#include除了可以包含扩展名.h的头文件外,也可以包含扩展名为.c的源程序文件 (3)如果文件1包含文件2,而在文件2中要用到文件3的内容,则可在文件1中用两个include指令分别包含文件2和文件3,而且用于包含文件3的包含指令应出现在用于包含文件2的包含指令之前,即在file1.c中依次给出如下两个incl

13、ude指令: #include “file3.h” #include “file2.h”,使用文件包含指令需要注意(续),(4)被包含文件(file2.h)与其所在的文件(即使用#include指令的源文件file1.c),在预处理后将合成为一个文件(而不是独立的两个文件)。因此,如果file2.h中有全局静态变量,它也在file1.c文件中有效,不必用extern进行声明。,习 题,一、选择题 (1)以下叙述中错误的是( ) A)在程序中凡是以”#”开始的代码行都是预处理指令行 B)预处理指令行的最后不能以分号表示结束 C)#define MAX是合法的宏定义指令行 D)C程序对预处理指令行

14、的处理是在程序执行的过程中进行的,习 题(续),(2)以下关于宏的叙述中正确的是( ) A)宏名必须用大写字母表示 B)宏定义必须位于源程序中所有语句之前 C)宏替换没有数据类型限制 D)宏调用比函数调用耗费时间,习 题(续),(3)若程序中有宏定义行( ) #define N 100 则以下叙述中正确的是 A)宏定义行中定义了标识符N的值为整数100 B)在编译程序对C源程序进行预处理时用100替换标识符N C)对C源程序进行编译时用100替换标识符N D)在运行时用100替换标识符N,习 题(续),二、编程题 (1)定义一个带参数的宏,实现求两个参数的最大值,并写出程序测试之。 (2)定义一个带参数的宏,使两个参数的值互换,并写出程序,输入两个数作为使用宏时的实参,并输出已交换后的两个值。 (3)编写程序,输入两个整数,求它们相除的余数。(用带参数的宏来实现) (4)试定义一个带参数的宏,实现参数的按格式输出。如printf(“The result is %dn”, a);,Thank You !,

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

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

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