C语言程序设计 教学课件 ppt 作者 李学军 第8章

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

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

1、2019/5/24,C语言程序设计,1,第8章 编译预处理,主要内容 宏定义与符号常量 文件包含 条件编译 核心知识点 宏定义 文件包含 条件编译,2019/5/24,C语言程序设计,2,重点难点 宏定义与符号常量 带参数的宏定义及使用 学习目标 了解预处理命令和C语句的区别 理解预处理和编译过程的区别 掌握预处理命令使用,第8章 编译预处理,2019/5/24,C语言程序设计,3,8.1 宏定义与符号常量,在C语言源程序中往往用一个指定的标识符(即名字)来代表一个字符串,称为“宏”,这个标识符称为“宏名”。 在源程序中可以出现这个宏名,称为“宏引用”或“宏调用”。 在编译预处理时,对源程序中

2、所有出现的“宏名”,均可用宏定义中的字符串去替换,这种将宏名替换成字符串的过程称为“宏替换”或“宏展开”。 为了区别于一般的变量名、数组名、指针变量名,宏名通常大写字母组成。宏分为无参数的宏(即无参宏)和有参数的宏(即有参宏)两种。 8.1.1无参数的宏定义 1一般格式 #define 标识符 字符串 其中“#”表示这是一条预处理命令。凡是以“#”开头的均为预处理命令。“define”为宏定义命令。“标识符”为所定义的宏名,“字符串”可以是常数、表达式和格式串等。在预编译时会将程序中出现的宏名替换为对应的字符串。 如: #define PI 3.1415926,2019/5/24,C语言程序设

3、计,4,2功能 它的作用是在程序中我们可以用PI来代替3.1415926;在编译预处理时,将程序中在该命令出现以后的所有PI都用3.1415926代替,每发现一个就进行相应的替换,只有在完成了这个过程之后才将源程序交给编译系统。这里将宏名替换为字符串的过程称为“宏展开”。 【例8-1】宏名的定义及应用。 #define PI 3.14 main() float r=2,area,l; l=2*r*PI; area=PI*r*r; printf(“PI=%f,area=%f,l=%f”,PI,area,l); 运行后输出: PI=3.140000,area=12.560000,l=12.5600

4、00,2019/5/24,C语言程序设计,5,3.说明 (1)宏名一般用大写字母,以区别其他标识符 (2)宏定义仅仅是符号替换,不是赋值语句,因此不做语法检查。 如在上例中,若写成:#define PI 3.14a,则预处理时照样代入,不管含义是否正确。只有在编译以被宏展开的源程序是才发现错误并报错。 (3)双引号中的宏名不进行替换。 如上例中输出PI=3.14时,只把双引号外面的PI进行了替换。 (4)宏名的有效范围是从定义命令之后直到本源文件结束,但也可以用undef提前终止宏的作用域。 例如: FM的有效作用域 #define FM 6.38 main() #undef FM void

5、f() 在函数f()中,FM不再是6.38,再用到FM时需重新定义。,2019/5/24,C语言程序设计,6,(5)使用宏定义可以嵌套,即后定义的宏中可以使用先定义的宏。 【例8-2】 宏名的嵌套定义及应用。 #define PI 3.14 #define R 2 #define S PI*R*R main() printf(“S=%f”,S); 运行输出:S=12.560000 经过宏展开后,输出项S被展开为:3.14*2*2,printf函数调用语句就相应的展开为:printf(“S=%f”, 3.14*2*2)。,2019/5/24,C语言程序设计,7,(6)当宏定义在一行中写不下需要换

6、行时,只需在最后一个字符后紧接着加一个反斜线“”。例如: #define LEAP_YEAR year%4=0 &year%100!=0|year%400=0 等价于:#define LEAP_YEAR year%4=0&year%100!=0|year%400=0 (7)使用宏可以减少程序中重复书写某些字符串的工作量,增强程序的易读性和可靠性。 8.1.2 带参数的宏定义 1.一般格式 #define 标识符(形参表) 形参表达式 如:#define MAX(a,b) (ab)?(a):(b),此处标识符S也就是宏名。 2.功能 预处理程序将程序中出现的所有带实参的宏名展开成有实参组成的表达

7、式。 如:max=MAX(2,3);,2019/5/24,C语言程序设计,8,【例8-3】 带参数的宏定义。 #define MAX(a,b) (ab)?(a):(b) main() int a=2,b=3,max; max=MAX(9,5); printf(“max=%dt“,max); max=MAX(a,b); printf(“max=%dn“,max); 运行输出为:max=9 max=3,2019/5/24,C语言程序设计,9,3.说明 (1)宏名与括号之间不可以有空格。 (2)有些参数表达式必须加上括号,否则在实参表达式替换时,会出现错误。 例如:#define S(x) x*x*

8、x main() a1=1;a2=2; x=S(a1+a2); 经过编译,该赋值语句变为x=a1+a2*a1+a2*a1+a2,并不是我们想要的x=(a1+a2)*(a1+a2)*(a1+a2),为了得到想要的结果,定义时应在字符串中的形式参数外面加一个括弧,即:#define S(x) (x)*(x)*(x)。 (3)带参数的宏与函数的区别 带参数的宏与函数类似,都有形参和实参,从效果上看有时也一样,但他们的本质是不同的,主要区别如下: 函数的形参和实参都要定义类型,二者要求一致;而宏不存在参数类型问题,只是一个符号代表,展开时代入指定的字符即可,宏定义时的字符串可以为任意类型。 函数调用影

9、响运行时间,宏替换影响编译时间。函数调用在运行时分配临时的内存单元,而宏替换在编译时进行,展开时不分配内存。,2019/5/24,C语言程序设计,10,函数只有一个返回值,而宏替换可能有多个结果。如: 【例8-4】 带参数的宏与函数的应用比较。 #define PI 3.14 #define R 2 #define C(S,L,V) S=PI*R*R;L=2*R*PI;V=4.0/3*PI*PI*PI main() float s,l,v; C(s,l,v); printf(“s=%f,l=%f,v=%f“,s,l,v); ,2019/5/24,C语言程序设计,11,使用宏的次数多时,宏展开后

10、使源程序增长;而函数调用不会使函数增长。 【例8-5】 分别用函数和带参数的宏,从三个数中找出最大者。 方法一:用函数实现,程序如下: main() int a,b,c; printf(“Please input three numbers:“); scanf(“%d,%d,%d“, ,2019/5/24,C语言程序设计,12,方法二:用带参数的宏实现,程序如下: #define MAX(a,b) (a)(b)?(a):(b) main() int a,b,c; printf(“Please input three numbers:“); scanf(“%d,%d,%d“, 两种方法最后运行效

11、果一样。运行结果如下: Please input three numbers:12,85,45 max of the three is 85,2019/5/24,C语言程序设计,13,8.2 文件包含,所谓文件包含是指将一个指定的文件的内容完全包含到当前的文件中,用#include命令来实现。 使用的一般格式为: #include “文件名” 或 #include 在预编译处理时,用指定的文件名的内容代替预处理命令,它可以节省程序设计人员的重复劳动。 例如,调用系统库函数中的字符串处理函数时,需要在程序的开始使用:#include“string.h”,表明将string.h文件的内容嵌入当前的

12、程序中。,2019/5/24,C语言程序设计,14,说明: (1)两种格式的区别:使用第一种形式时,预处理程序首先在引用被包含文件的源文件所在的目录中寻找指定的文件,如果没有找到,再按照系统指定的标准目录查找。使用第二种形式时,预处理程序直接在标准目录下查找指定的文件。 (2)一个#include只能包含一个文件,如果要包含N个文件,则要用N个#include命令。 (3)被包含的文件一定是文本文件,不可以是执行程序或目标文件。 (4)文件包含也可以嵌套。如果文件1包含文件2,而文件2中要用到文件3的内容,则可在文件1中用两个include命令分别包含文件2和文件3,而且文件3应出现在文件2之

13、前,即在file1.c中定义: #include“file3.h” #include“file2.h” 这样,file1和file2都可以用file3的内容。在file2中不必再用#include了。 (5)当包含文件修改后,对包含该文件的源程序必须重新进行编译连接。,2019/5/24,C语言程序设计,15,8.3 条件编译,预处理程序提供了条件编译的功能。 可以按不同的条件去编译不同的程序部分,因而产生不同的目标代码文件。 这对于程序的移植和调试是很有用的。 条件编译有三种形式 1. 第一种形式:#ifdef #else #endif语句,格式为: #ifdef 标识符 程序段1 #els

14、e 程序段2 #endif 它的功能是,如果标识符已被 #define命令定义过则对程序段1进行编译;否则对程序段2进行编译。如果没有程序段2(它为空),本格式中的#else可以没有, 即可以写为: #ifdef 标识符 程序段 #endif #define NUM ok ,2019/5/24,C语言程序设计,16,【例8-6】条件编译的应用举例。 #define DEBUG main() int i,sum=0; for(i=1;i=10;i+) sum=sum+2; #ifdef DEBUG printf(“%d,“,sum); #endif printf(“The sum is %d“,

15、sum); 运行结果: 2,4,6,8,10,12,14,16,18,20,The sum is 20 如果在程序中删除“#define DEBUG”,则程序的运行结果将变为:“The sum is 20”。,2019/5/24,C语言程序设计,17,2第二种形式:#ifndef #else #endif语句,格式为: #ifndef 标识符 程序段1 #else 程序段2 #endif 这种形式与第一种形式的区别是将“ifdef”变为“ifndef”。它的功能变为:如果标识符没有被 #define命令定义过则对程序段1进行编译;否则对程序段2进行编译。同样它也可以省略掉#else分支,其应用

16、与形式一类同。 3第三种形式:#if #else endif语句,格式为: #if 表达式 程序段1 #else 程序段2 #endif 它的功用是:当表达式的值为非0时,编译程序段1;否则编译程序段2,其#else部分可以省略。需要注意的是,这个表达式不是运行时的表达式,必须是在编译时就能知道它的值。,2019/5/24,C语言程序设计,18,【例8-7】根据需要设置条件编译,使之能将字母全改为大写输出,或全改为小写字母输出。 #define LETTER 1 main() int i,n;char c; char ch=“My name is ZHANG_LIN!“; n=strlen(ch); for(i=0;i =a ,2019/5/24,C语言程序设计,19,运行结果为: MY NAME IS ZHANG_LIN! 若将define LETTER 1变成define LETTER 0后,

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


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

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