《之预处理命令》PPT课件.ppt

上传人:新** 文档编号:568206342 上传时间:2024-07-23 格式:PPT 页数:25 大小:745.51KB
返回 下载 相关 举报
《之预处理命令》PPT课件.ppt_第1页
第1页 / 共25页
《之预处理命令》PPT课件.ppt_第2页
第2页 / 共25页
《之预处理命令》PPT课件.ppt_第3页
第3页 / 共25页
《之预处理命令》PPT课件.ppt_第4页
第4页 / 共25页
《之预处理命令》PPT课件.ppt_第5页
第5页 / 共25页
点击查看更多>>
资源描述

《《之预处理命令》PPT课件.ppt》由会员分享,可在线阅读,更多相关《《之预处理命令》PPT课件.ppt(25页珍藏版)》请在金锄头文库上搜索。

1、第第第第4 4 4 4章章章章 之预处理命令之预处理命令之预处理命令之预处理命令 第第4 4章:之预处理命令章:之预处理命令 u学习的意义学习的意义 语语言言程程序序设设计计教教程程 第第4章章 预预处处理理命命令令C C C C C语言的一个重要特征是它的语言的一个重要特征是它的语言的一个重要特征是它的语言的一个重要特征是它的预处理功能预处理功能预处理功能预处理功能。我们知道,一。我们知道,一。我们知道,一。我们知道,一个高级语言源程序在计算机上运行,必须先用编译程序将其个高级语言源程序在计算机上运行,必须先用编译程序将其个高级语言源程序在计算机上运行,必须先用编译程序将其个高级语言源程序在

2、计算机上运行,必须先用编译程序将其翻译为机器语言。编译包括词法分析、语法分析、代码生成、翻译为机器语言。编译包括词法分析、语法分析、代码生成、翻译为机器语言。编译包括词法分析、语法分析、代码生成、翻译为机器语言。编译包括词法分析、语法分析、代码生成、代码优化等步骤,有时在编译之前还要做某些预处理工作,代码优化等步骤,有时在编译之前还要做某些预处理工作,代码优化等步骤,有时在编译之前还要做某些预处理工作,代码优化等步骤,有时在编译之前还要做某些预处理工作,如去掉注释,变换格式等。如去掉注释,变换格式等。如去掉注释,变换格式等。如去掉注释,变换格式等。C C C C语言允许在源程序中包含预处理语言

3、允许在源程序中包含预处理语言允许在源程序中包含预处理语言允许在源程序中包含预处理命令,在正式编译之前(词法分析之前)系统先对这些命令命令,在正式编译之前(词法分析之前)系统先对这些命令命令,在正式编译之前(词法分析之前)系统先对这些命令命令,在正式编译之前(词法分析之前)系统先对这些命令进行进行进行进行“预处理预处理预处理预处理”,然后,然后,然后,然后再再再再对整个源程序进行通常的编译处理。对整个源程序进行通常的编译处理。对整个源程序进行通常的编译处理。对整个源程序进行通常的编译处理。从语法上讲,这些预处理命令不是从语法上讲,这些预处理命令不是从语法上讲,这些预处理命令不是从语法上讲,这些预

4、处理命令不是C C C C语言的一部分,但使用它语言的一部分,但使用它语言的一部分,但使用它语言的一部分,但使用它们却扩展了们却扩展了们却扩展了们却扩展了C C C C语言程序设计的环境,可以简化程序开发过程,语言程序设计的环境,可以简化程序开发过程,语言程序设计的环境,可以简化程序开发过程,语言程序设计的环境,可以简化程序开发过程,提高程序的可读性,也更有利于移植和调试提高程序的可读性,也更有利于移植和调试提高程序的可读性,也更有利于移植和调试提高程序的可读性,也更有利于移植和调试C C C C语言程序。本讲语言程序。本讲语言程序。本讲语言程序。本讲主要介绍主要介绍主要介绍主要介绍宏定义宏定

5、义宏定义宏定义、文件包括文件包括文件包括文件包括和和和和条件编译条件编译条件编译条件编译等预处理命令。等预处理命令。等预处理命令。等预处理命令。 u学习的意义学习的意义 语语言言程程序序设设计计教教程程 第第4章章 预预处处理理命命令令C源程序生成执行文件的过程:源程序生成执行文件的过程:源程序生成执行文件的过程:源程序生成执行文件的过程:.c .c或或或或. .cppcpp编译编译编译编译. .obobj j链接链接链接链接.ex.exe e#include #include #define PI 3.14159#define PI 3.14159void main ( )void main

6、 ( ) float r = 4; float r = 4; printfprintf (“s = % (“s = %fnfn”, PI*r*r);”, PI*r*r); 预处理命令预处理命令预处理命令预处理命令预处理预处理预处理预处理本本本本讲讲讲讲讨讨讨讨论论论论之之之之重点!重点!重点!重点!u学习目标学习目标 u学习内容学习内容 预处理命令简介预处理命令简介预处理命令简介预处理命令简介宏定义宏定义宏定义宏定义l l 不带参数的宏定义不带参数的宏定义不带参数的宏定义不带参数的宏定义l l 带参数的宏定义带参数的宏定义带参数的宏定义带参数的宏定义文件包含文件包含文件包含文件包含条件编译条件

7、编译条件编译条件编译本章小结本章小结本章小结本章小结掌握掌握掌握掌握#include#include、#define#define、#if#if、# #ifdefifdef、#else#else、# #ifndefifndef和和和和 # #endifendif等命令的用法;等命令的用法;等命令的用法;等命令的用法;掌握宏定义和宏替换的一般方法;掌握宏定义和宏替换的一般方法;掌握宏定义和宏替换的一般方法;掌握宏定义和宏替换的一般方法;掌握包含文件的处理方法;掌握包含文件的处理方法;掌握包含文件的处理方法;掌握包含文件的处理方法;了解条件编译的作用和实现方法。了解条件编译的作用和实现方法。了解条

8、件编译的作用和实现方法。了解条件编译的作用和实现方法。语语言言程程序序设设计计教教程程 第第4章章 预预处处理理命命令令C重点!重点!4.9 4.9 预处理命令简介预处理命令简介 预处理命令:预处理命令:预处理命令:预处理命令:C C C C源程序中以源程序中以源程序中以源程序中以# # # #开头、以换行符结尾的行开头、以换行符结尾的行开头、以换行符结尾的行开头、以换行符结尾的行 语语言言程程序序设设计计教教程程 第第4章章 预预处处理理命命令令C 种类:种类:种类:种类:l l 宏定义宏定义宏定义宏定义 #define#define、# #undefundefl l 文件包含文件包含文件包

9、含文件包含 #include#includel l 条件编译条件编译条件编译条件编译 #if#if、# #ifdefifdef、#else#else、# #elifelif、# #endifendif等等等等l l 其他其他其他其他 #line#line、#error#error、# #pragpragmma a等等等等本讲主要讨论的本讲主要讨论的本讲主要讨论的本讲主要讨论的内容!内容!内容!内容! 格式:格式:格式:格式:l l “ “#”#”开头开头开头开头l l 占单独书写行占单独书写行占单独书写行占单独书写行l l 语句尾不加分号语句尾不加分号语句尾不加分号语句尾不加分号4.10 4.

10、10 宏定义宏定义 宏定义分为两种:宏定义分为两种:宏定义分为两种:宏定义分为两种:不带参数的宏定义不带参数的宏定义不带参数的宏定义不带参数的宏定义和和和和带参数的宏定义带参数的宏定义带参数的宏定义带参数的宏定义。 语语言言程程序序设设计计教教程程 第第4章章 预预处处理理命命令令C1 1 1 1、不带参数的宏定义、不带参数的宏定义、不带参数的宏定义、不带参数的宏定义 一般形式一般形式一般形式一般形式 #define #define 标识符标识符标识符标识符 单词串单词串单词串单词串 指令名称指令名称指令名称指令名称宏名,被定义代表宏名,被定义代表宏名,被定义代表宏名,被定义代表后面的单词串后

11、面的单词串后面的单词串后面的单词串 宏体,是宏的内宏体,是宏的内宏体,是宏的内宏体,是宏的内容文本容文本容文本容文本 可缺省,表示宏名可缺省,表示宏名可缺省,表示宏名可缺省,表示宏名定义过或取消宏体定义过或取消宏体定义过或取消宏体定义过或取消宏体 功能功能功能功能 用指定标识符用指定标识符用指定标识符用指定标识符( ( ( (宏名宏名宏名宏名) ) ) )代替字符序列代替字符序列代替字符序列代替字符序列( ( ( (宏体宏体宏体宏体) ) ) )如如如如 #define YES 1#define YES 1 #define NO 0 #define NO 0 #define PI 3.1415

12、926 #define PI 3.1415926 #define OUT #define OUT printf(“Hello,Worldprintf(“Hello,World”);”);#define #define SIZE SIZE 9 9#define #define INT_STRINT_STR %d%d void main ( )void main ( ) intint aaSIZESIZE, i; , i; for (i = 0; i for (i = 0; i = 0; i-) - 1; i = 0; i-) printfprintf ( (INT_STRINT_STR, , a

13、iai); ); 宏定义宏定义宏定义宏定义void main ( )void main ( ) intint a a9 9, i; , i; for (i = 0; i for (i = 0; i = 0; i-) - 1; i = 0; i-) printfprintf ( (%d%d, , aiai); ); 预编译预编译预编译预编译处理后处理后处理后处理后 注意:注意:宏替换时仅仅是将源程序中与宏名相同的宏替换时仅仅是将源程序中与宏名相同的标识符替换成宏的内容文本,并不对宏的内容文本做标识符替换成宏的内容文本,并不对宏的内容文本做任何处理。任何处理。语语言言程程序序设设计计教教程程 第第

14、4章章 预预处处理理命命令令C 宏定义注意事项宏定义注意事项宏定义注意事项宏定义注意事项 l l C C C C程序员通常用程序员通常用程序员通常用程序员通常用大写字母大写字母大写字母大写字母来定义宏名,以便与变量名区别。来定义宏名,以便与变量名区别。来定义宏名,以便与变量名区别。来定义宏名,以便与变量名区别。 如:如:如:如: #define #define PIPI 3.14159 3.14159l l 宏定义的宏定义的宏定义的宏定义的位置任意位置任意位置任意位置任意,但,但,但,但一般放在函数外面一般放在函数外面一般放在函数外面一般放在函数外面。 l l 宏定义时,如果单词串太长,需要写

15、多行,可以在行尾宏定义时,如果单词串太长,需要写多行,可以在行尾宏定义时,如果单词串太长,需要写多行,可以在行尾宏定义时,如果单词串太长,需要写多行,可以在行尾使用反斜线使用反斜线使用反斜线使用反斜线“ ”续行符续行符续行符续行符 例如:例如:例如:例如:#define LONG_STRING this is a very long string that is#define LONG_STRING this is a very long string that is used as an exampleused as an examplel l 宏名的宏名的宏名的宏名的作用域作用域作用域作用

16、域是从是从是从是从#define#define定义之后直到该宏定义所在定义之后直到该宏定义所在定义之后直到该宏定义所在定义之后直到该宏定义所在文件结束文件结束文件结束文件结束 l l # # # #undefundefundefundef可可可可终止宏名作用域终止宏名作用域终止宏名作用域终止宏名作用域# #undefundef 标识符标识符标识符标识符#define YES 1#define YES 1void main ( )void main ( ) . . # #undefundef YES YES#define YES 0#define YES 0void max ( )void ma

17、x ( ) . . YESYES原作用域原作用域原作用域原作用域YESYES新新新新作用域作用域作用域作用域l l 宏定义可以宏定义可以宏定义可以宏定义可以嵌套定义嵌套定义嵌套定义嵌套定义,但不能递归定义,但不能递归定义,但不能递归定义,但不能递归定义 #define R 2.0 #define R 2.0 #define PI 3.14159#define PI 3.14159#define L 2*PI*R (#define L 2*PI*R ( ) )#define S PI*R*R (#define S PI*R*R ( ) )#define M M + 9 (#define M M

18、+ 9 ( ) )l l 程序中字符串常量即双引号中的字符,不作为宏进行宏程序中字符串常量即双引号中的字符,不作为宏进行宏程序中字符串常量即双引号中的字符,不作为宏进行宏程序中字符串常量即双引号中的字符,不作为宏进行宏替换操作替换操作替换操作替换操作 #define XYZ this is a test #define XYZ this is a test printf(XYZprintf(XYZ););输出:输出:输出:输出:XYZXYZ,而不是:,而不是:,而不是:,而不是:this is a testthis is a test。#include #include stdio.hstdi

19、o.h #define XYZ test#define XYZ testmain() char test=This is a Test!;main() char test=This is a Test!;printf(XYZ%s,XYZprintf(XYZ%s,XYZ); ); 输出:输出:输出:输出: XYZThisXYZThis is a Test is a Test ! !语语言言程程序序设设计计教教程程 第第4章章 预预处处理理命命令令C 宏定义注意事项宏定义注意事项宏定义注意事项宏定义注意事项 l l 宏定义一般以宏定义一般以宏定义一般以宏定义一般以换行结束换行结束换行结束换行结束,

20、不要用分号结束,以免引起不,不要用分号结束,以免引起不,不要用分号结束,以免引起不,不要用分号结束,以免引起不必要的错误必要的错误必要的错误必要的错误 #define PI #define PI 3.143.14; ; a = PI * 2 * 2;a = PI * 2 * 2; 预编译预编译预编译预编译处理后处理后处理后处理后a = a = 3.143.14; ; * 2 * 2; * 2 * 2; 错误!错误!错误!错误!l l 宏可以被宏可以被宏可以被宏可以被重复定义重复定义重复定义重复定义。 #define N 9#define N 9 / /第一次宏定义第一次宏定义第一次宏定义第一次

21、宏定义intint f ( ) f ( ) N N的内容是的内容是的内容是的内容是9 9 return (N * N); return (N * N); #define N 20#define N 20 / /第二次宏定义第二次宏定义第二次宏定义第二次宏定义void main ( )void main ( ) N N的内容是的内容是的内容是的内容是2020 printfprintf (% (%dndn, N + f ( );, N + f ( ); l l 在定义宏时,如果宏是一个表达式,那么一定要将这个在定义宏时,如果宏是一个表达式,那么一定要将这个在定义宏时,如果宏是一个表达式,那么一定要

22、将这个在定义宏时,如果宏是一个表达式,那么一定要将这个表达式用()括起来,否则可能会引起非预期的结果。表达式用()括起来,否则可能会引起非预期的结果。表达式用()括起来,否则可能会引起非预期的结果。表达式用()括起来,否则可能会引起非预期的结果。 #define NUM1 10#define NUM1 10#define NUM2 20#define NUM2 20#define NUM NUM1 + NUM2 #define NUM NUM1 + NUM2 void main ( )void main ( ) intint a = 2, b = 3; a = 2, b = 3; a *= a

23、 *= NUMNUM; ; b = b * b = b * NUMNUM; ; printfprintf (a = %d, b = % (a = %d, b = %dndn, a, b); , a, b); void main ( )void main ( ) intint a = 2, b = 3; a = 2, b = 3; a *= a *= 10 + 20 10 + 20 ; ; b = b * b = b * 10 + 20 10 + 20 ; ; printfprintf (a = %d, b = % (a = %d, b = %dndn, a, b); , a, b); 预编译预

24、编译预编译预编译处理后处理后处理后处理后输出结果:输出结果:输出结果:输出结果:a = 60, b = 50a = 60, b = 50 ( () )( () )( () )输出结果:输出结果:输出结果:输出结果:a = 60, b = 90a = 60, b = 90 语语言言程程序序设设计计教教程程 第第4章章 预预处处理理命命令令C2 2 2 2、带参数的宏定义、带参数的宏定义、带参数的宏定义、带参数的宏定义 一般形式一般形式一般形式一般形式 #define #define 标识符标识符标识符标识符( (参数列表参数列表参数列表参数列表) ) 单词串单词串单词串单词串通常会引用通常会引用

25、通常会引用通常会引用宏的参数宏的参数宏的参数宏的参数 例:例:例:例: #define #define S(aS(a, b) a*b, b) a*b . . area = S(3, 2); area = S(3, 2);宏展开:宏展开:宏展开:宏展开: area=3*2;area=3*2;宏展开:宏展开:宏展开:宏展开:形参用实参形参用实参形参用实参形参用实参替替替替换,其它字符保留换,其它字符保留换,其它字符保留换,其它字符保留宏体及各形参外一般应加括号宏体及各形参外一般应加括号宏体及各形参外一般应加括号宏体及各形参外一般应加括号()()()()不能有空格不能有空格不能有空格不能有空格例例例

26、例 #define S #define S (r) PI*r*r(r) PI*r*r相当于定义了相当于定义了相当于定义了相当于定义了不带参数的不带参数的不带参数的不带参数的宏宏宏宏S S,代表字符串代表字符串代表字符串代表字符串“(“(r) PI*r*r”r) PI*r*r” 例例例例 #define POWER(x) x*x#define POWER(x) x*x x=4; y=6; x=4; y=6; z=POWER(x+y); z=POWER(x+y);宏展开:宏展开:宏展开:宏展开:z=z=x+yx+y* *x+yx+y; ;但是但是但是但是: # #define POWER(x) d

27、efine POWER(x) ( ( (x x) )* *( (x x) ) )的的的的宏展开:宏展开:宏展开:宏展开: z=(x+y)*(x+y);z=(x+y)*(x+y);参数表由一个或多个参数构成,参数只有参数名参数表由一个或多个参数构成,参数只有参数名参数表由一个或多个参数构成,参数只有参数名参数表由一个或多个参数构成,参数只有参数名或字面常量或字面常量或字面常量或字面常量,没有数据类型符,参数之间用逗,没有数据类型符,参数之间用逗,没有数据类型符,参数之间用逗,没有数据类型符,参数之间用逗号号号号隔开,参数名必须是合法的标识符隔开,参数名必须是合法的标识符隔开,参数名必须是合法的标

28、识符隔开,参数名必须是合法的标识符 #define #define MAX(xMAX(x, y) (x)(y)?(x):(y), y) (x)(y)?(x):(y) . .void main ( )void main ( ) intint a, b, c, d, t; a, b, c, d, t; . . t = t = MAX(a+bMAX(a+b, , c+dc+d); ); 宏展开:宏展开:宏展开:宏展开:t = (a+b)(c+d)?(a+b):(c+d);t = (a+b)(c+d)?(a+b):(c+d);intint max(intmax(int x,intx,int y) y)

29、 return(xreturn(x y ? x : y); y ? x : y); void main ( )void main ( ) intint a, b, c, d, t; a, b, c, d, t; . . t = t = max(a+bmax(a+b, , c+dc+d); ); 【例例例例】用宏定义和函数实现同样的功能用宏定义和函数实现同样的功能用宏定义和函数实现同样的功能用宏定义和函数实现同样的功能语语言言程程序序设设计计教教程程 第第4章章 预预处处理理命命令令C带参的宏与函数区别带参的宏与函数区别带参的宏与函数区别带参的宏与函数区别语语言言程程序序设设计计教教程程 第第4

30、章章 预预处处理理命命令令C带参宏带参宏带参宏带参宏函数函数函数函数处理时间处理时间处理时间处理时间编译时编译时编译时编译时程序运行时程序运行时程序运行时程序运行时参数类型参数类型参数类型参数类型无类型问题无类型问题无类型问题无类型问题定义实参、形参类型定义实参、形参类型定义实参、形参类型定义实参、形参类型处理过程处理过程处理过程处理过程不分配内存,简单的不分配内存,简单的不分配内存,简单的不分配内存,简单的字符置换字符置换字符置换字符置换分配内存,先求实参值,分配内存,先求实参值,分配内存,先求实参值,分配内存,先求实参值,再代入形参再代入形参再代入形参再代入形参程序长度程序长度程序长度程序

31、长度增长增长增长增长不变不变不变不变运行速度运行速度运行速度运行速度不占运行时间不占运行时间不占运行时间不占运行时间调用和返回占时间调用和返回占时间调用和返回占时间调用和返回占时间4.11 4.11 文件包含文件包含处理过程处理过程处理过程处理过程语语言言程程序序设设计计教教程程 第第4章章 预预处处理理命命令令C 功能功能功能功能 一个源文件可将另一个源文件的内容全部包含进来一个源文件可将另一个源文件的内容全部包含进来一个源文件可将另一个源文件的内容全部包含进来一个源文件可将另一个源文件的内容全部包含进来 一般形式一般形式一般形式一般形式#include#include 或或或或 # # i

32、ncludeinclude “ “包含文件名包含文件名包含文件名包含文件名” ” 预编译时预编译时预编译时预编译时, , , ,用被包含文件的内容取代该预处理命令,再用被包含文件的内容取代该预处理命令,再用被包含文件的内容取代该预处理命令,再用被包含文件的内容取代该预处理命令,再对对对对“包含包含包含包含”后的文件作一个源文件编译后的文件作一个源文件编译后的文件作一个源文件编译后的文件作一个源文件编译: 直直直直接到系统指定的接到系统指定的接到系统指定的接到系统指定的“文件包含目录文件包含目录文件包含目录文件包含目录”去查去查去查去查找被包含的文件找被包含的文件找被包含的文件找被包含的文件 “

33、 ”“ ”“ ”“ ”: : : :系统首先到当前目系统首先到当前目系统首先到当前目系统首先到当前目录下查找被包含文件,如录下查找被包含文件,如录下查找被包含文件,如录下查找被包含文件,如果没找到,再到系统果没找到,再到系统果没找到,再到系统果没找到,再到系统指定指定指定指定的的的的“文件包含目录文件包含目录文件包含目录文件包含目录”去查去查去查去查找。找。找。找。 预编译预编译预编译预编译处理后处理后处理后处理后A A源文件源文件源文件源文件prg1.cprg1.c#include prg1.c#include prg1.c B B源文件源文件源文件源文件prg2.cprg2.cB BA A

34、新源文件新源文件新源文件新源文件prg2.cprg2.c语语言言程程序序设设计计教教程程 第第4章章 预预处处理理命命令令C文件包含举例文件包含举例文件包含举例文件包含举例: : : :#include #include head.hhead.h #include #include func.cfunc.c void main ( ) void main ( ) intint a , b, c; a , b, c; a = a = getnumgetnum ( ); ( ); b = b = getnumgetnum ( ); ( ); c = max ( c = max ( max(amax

35、(a, b), NUM ); , b), NUM ); printfprintf (MAX = % (MAX = %dndn, c ); , c ); (stdio.hstdio.h文件中的内容)文件中的内容)文件中的内容)文件中的内容) #define NUM 9 #define NUM 9 intint max ( max (intint x, x, intint y) y) return (x y ? x : y); return (x y ? x : y); intint getnumgetnum ( ) ( ) intint a; a; scanf(%dscanf(%d, &a),

36、&a) return (a); return (a); void main ( ) void main ( ) intint a , b, c; a , b, c; a = a = getnumgetnum ( ); ( ); b = b = getnumgetnum ( ); ( ); c = max ( c = max ( max(amax(a, b), NUM ); , b), NUM ); printfprintf (MAX = % (MAX = %dndn, c ); , c ); /*/*head.hhead.h的内容的内容的内容的内容* */ /#include #include

37、 #define NUM 9#define NUM 9/*/*func.cfunc.c的内容的内容的内容的内容* */ /intint max ( max (intint x, x, intint y) y) return (x y ? x : y); return (x y ? x : y); intint getnumgetnum ( ) ( ) intint a; a; scanf(%dscanf(%d, &a), &a) return (a); return (a); 预编译预编译预编译预编译处理后处理后处理后处理后语语言言程程序序设设计计教教程程 第第4章章 预预处处理理命命令令C文

38、件包含的优点文件包含的优点文件包含的优点文件包含的优点: : : : 一个大程序,通常分为多个模块,并由多个程序员分别一个大程序,通常分为多个模块,并由多个程序员分别一个大程序,通常分为多个模块,并由多个程序员分别一个大程序,通常分为多个模块,并由多个程序员分别编程。有了文件包含处理功能,就可以将多个模块共用的数编程。有了文件包含处理功能,就可以将多个模块共用的数编程。有了文件包含处理功能,就可以将多个模块共用的数编程。有了文件包含处理功能,就可以将多个模块共用的数据(如符号常量和数据结构)或函数,集中到一个单独的文据(如符号常量和数据结构)或函数,集中到一个单独的文据(如符号常量和数据结构)

39、或函数,集中到一个单独的文据(如符号常量和数据结构)或函数,集中到一个单独的文件中(如上例中的文件件中(如上例中的文件件中(如上例中的文件件中(如上例中的文件head.hhead.hhead.hhead.h和和和和func.cfunc.cfunc.cfunc.c)。这样,凡是要使)。这样,凡是要使)。这样,凡是要使)。这样,凡是要使用其中数据或调用其中函数的程序员,只要使用文件包含处用其中数据或调用其中函数的程序员,只要使用文件包含处用其中数据或调用其中函数的程序员,只要使用文件包含处用其中数据或调用其中函数的程序员,只要使用文件包含处理功能,将所需文件包含进来即可,不必再重复定义它们,理功能

40、,将所需文件包含进来即可,不必再重复定义它们,理功能,将所需文件包含进来即可,不必再重复定义它们,理功能,将所需文件包含进来即可,不必再重复定义它们,从而减少重复劳动。从而减少重复劳动。从而减少重复劳动。从而减少重复劳动。 文件包含的几点说明文件包含的几点说明文件包含的几点说明文件包含的几点说明 常用在文件头部的被包含文件,称为常用在文件头部的被包含文件,称为常用在文件头部的被包含文件,称为常用在文件头部的被包含文件,称为“标题文件标题文件标题文件标题文件”或或或或“头头头头部文件部文件部文件部文件”,常以常以常以常以.h.h.h.h(headheadheadhead)作为后缀,简称头文件)作

41、为后缀,简称头文件)作为后缀,简称头文件)作为后缀,简称头文件。在头文。在头文。在头文。在头文件中,除可包含宏定义外,还可包含外部变量定义、结构类件中,除可包含宏定义外,还可包含外部变量定义、结构类件中,除可包含宏定义外,还可包含外部变量定义、结构类件中,除可包含宏定义外,还可包含外部变量定义、结构类型定义等。型定义等。型定义等。型定义等。 一条包含命令,只能指定一个被包含文件一条包含命令,只能指定一个被包含文件一条包含命令,只能指定一个被包含文件一条包含命令,只能指定一个被包含文件。如果要包含。如果要包含。如果要包含。如果要包含n n n n个文件,则要用个文件,则要用个文件,则要用个文件,

42、则要用n n n n条包含命令。条包含命令。条包含命令。条包含命令。 文件包含可以嵌套文件包含可以嵌套文件包含可以嵌套文件包含可以嵌套,即被包含文件中又包含另一个文件。,即被包含文件中又包含另一个文件。,即被包含文件中又包含另一个文件。,即被包含文件中又包含另一个文件。 4.12 4.12 条件编译条件编译语语言言程程序序设设计计教教程程 第第4章章 预预处处理理命命令令C根据一定的条件去编译源文件的不同部分,这就是根据一定的条件去编译源文件的不同部分,这就是根据一定的条件去编译源文件的不同部分,这就是根据一定的条件去编译源文件的不同部分,这就是条件编译条件编译条件编译条件编译。1 1、#if

43、 #if # #endifendif形式形式形式形式 格式:格式:格式:格式:#if#if 条件条件条件条件1 1 程序段程序段程序段程序段1 1# #elifelif 条件条件条件条件2 2 程序段程序段程序段程序段2 2 #else#else 程序段程序段程序段程序段n n# #endifendif常量表达式。通常会用到宏名,常量表达式。通常会用到宏名,常量表达式。通常会用到宏名,常量表达式。通常会用到宏名,条件可以不加括号条件可以不加括号条件可以不加括号条件可以不加括号“()()()()” # #elifelif和和和和#else#else可可可可以没有以没有以没有以没有 # #endi

44、fendif必须存在,必须存在,必须存在,必须存在,它是它是它是它是#if#if命令的结尾命令的结尾命令的结尾命令的结尾 如果条件如果条件如果条件如果条件1 1 1 1为真就编译程序段为真就编译程序段为真就编译程序段为真就编译程序段1 1 1 1,否,否,否,否则如果条件则如果条件则如果条件则如果条件2 2 2 2为真就编译程序段为真就编译程序段为真就编译程序段为真就编译程序段2 2 2 2,如果各条件都不为真就编译程,如果各条件都不为真就编译程,如果各条件都不为真就编译程,如果各条件都不为真就编译程序段序段序段序段n n n n。 作用:作用:作用:作用: #if#if和和和和# #elif

45、elif常常与常常与常常与常常与defineddefined命令配命令配命令配命令配合使用,合使用,合使用,合使用,defineddefined命令的格式为命令的格式为命令的格式为命令的格式为: : defineddefined(宏名)(宏名)(宏名)(宏名) 或或或或 defined defined 宏名宏名宏名宏名功能:功能:功能:功能:判断某个宏是否已经定义,如果已经定义,判断某个宏是否已经定义,如果已经定义,判断某个宏是否已经定义,如果已经定义,判断某个宏是否已经定义,如果已经定义,defineddefined命令返回命令返回命令返回命令返回1 1,否则返回,否则返回,否则返回,否则返

46、回0 0。defineddefined命令只能与命令只能与命令只能与命令只能与#if#if或或或或# #elifelif配配配配合使用,不能单独使用。合使用,不能单独使用。合使用,不能单独使用。合使用,不能单独使用。 例如:例如:例如:例如:#if defined#if defined(USAUSA)的含义是)的含义是)的含义是)的含义是“ “如果定义了宏如果定义了宏如果定义了宏如果定义了宏USA”USA”。 例:下面的程序利用例:下面的程序利用例:下面的程序利用例:下面的程序利用ACTIVE_COUNTRYACTIVE_COUNTRY定义货币的名称定义货币的名称定义货币的名称定义货币的名称

47、语语言言程程序序设设计计教教程程 第第4章章 预预处处理理命命令令C#define USA 0#define USA 0#define ENGLAND 1 #define ENGLAND 1 #define FRANCE 2 #define FRANCE 2 #define ACTIVE_COUNTRY USA#define ACTIVE_COUNTRY USA #if ACTIVE_COUNTRY = USA #if ACTIVE_COUNTRY = USA char currency = “dollar”;char currency = “dollar”; / /有效有效有效有效 # #e

48、lifelif ACTIVE_COUNTRY = ENGLAND ACTIVE_COUNTRY = ENGLAND char currency = pound char currency = pound ; ; #else #else char currency = char currency = francefrance ; ; # #endifendif void main ( ) void main ( ) float price1, price2, float price1, price2, sumpricesumprice; ; scanfscanf (% (%f%ff%f, &pr

49、ice1,&price2); , &price1,&price2); sumpricesumprice = price1 + price2; = price1 + price2; printfprintf (sum = %.2f%s, (sum = %.2f%s, sumpricesumprice, currency); , currency); char currency = “dollar”;char currency = “dollar”; void main ( ) void main ( ) float price1, price2, float price1, price2, su

50、mpricesumprice; ; scanfscanf (% (%f%ff%f, &price1,&price2); , &price1,&price2); sumpricesumprice = price1 + price2; = price1 + price2; printfprintf (sum = %.2f%s, (sum = %.2f%s, sumpricesumprice, currency); , currency); 预编译预编译预编译预编译处理后处理后处理后处理后语语言言程程序序设设计计教教程程 第第4章章 预预处处理理命命令令C2 2、# #ifdefifdef # #e

51、ndifendif形式形式形式形式 格式:格式:格式:格式:# #ifdefifdef 宏名宏名宏名宏名 程序段程序段程序段程序段1 1#else#else 程序段程序段程序段程序段2 2# #endifendif等价于等价于等价于等价于“ “#if defined#if defined(宏名)(宏名)(宏名)(宏名)” ” 在在在在# #ifdefifdef和和和和#else#else之间可以之间可以之间可以之间可以加多个加多个加多个加多个# #elifelif命命命命令令令令 如果宏名已被如果宏名已被如果宏名已被如果宏名已被#define#define行定义,则编译程序段行定义,则编译程序

52、段行定义,则编译程序段行定义,则编译程序段1 1,否则编,否则编,否则编,否则编译程序段译程序段译程序段译程序段2 2 作用:作用:作用:作用:#define INTEGER 1#define INTEGER 1# #ifdefifdef INTEGER INTEGER intint add ( add (intint x, x, intint y) y) / /有效有效有效有效 return (x + y); return (x + y); #else #else float add (float x, float y) float add (float x, float y) return

53、(xreturn(x + y); + y); # #endifendif void main ( ) void main ( ) # #ifdefifdef INTEGER INTEGER intint a, b, c; a, b, c; / /有效有效有效有效 scanf(%d%dscanf(%d%d, &a, &b); , &a, &b); printf(aprintf(a + b = % + b = %dndn ,add (a, b); add (a, b); #else #else float a, b, c; float a, b, c; scanfscanf (% (%f%ff%f

54、, &a, &b); , &a, &b); printfprintf (a + b = % (a + b = %fnfn ,add (a, b); add (a, b); # #endifendif intint add ( add (intint x, x, intint y) y) / /有效有效有效有效 return (x + y); return (x + y); void main ( ) void main ( ) intint a, b, c; a, b, c; / /有效有效有效有效 scanf(%d%dscanf(%d%d, &a, &b); , &a, &b); print

55、f(aprintf(a + b = % + b = %dndn ,add (a, b); add (a, b); 预编译预编译预编译预编译处理后处理后处理后处理后语语言言程程序序设设计计教教程程 第第4章章 预预处处理理命命令令C3 3、# #ifndefifndef # #endifendif形式形式形式形式 格式:格式:格式:格式:# #ifndefifndef 宏名宏名宏名宏名 程序段程序段程序段程序段1 1#else#else 程序段程序段程序段程序段2 2# #endifendif如果宏名没被如果宏名没被如果宏名没被如果宏名没被#define#define行定义,则编译程序段行定义,

56、则编译程序段行定义,则编译程序段行定义,则编译程序段1 1,否则编,否则编,否则编,否则编译程序段译程序段译程序段译程序段2 2 作用:作用:作用:作用:条件编译与分支语句二者之间的差别:条件编译与分支语句二者之间的差别:条件编译与分支语句二者之间的差别:条件编译与分支语句二者之间的差别: 条件编译是在预编译时处理;而条件语句则是在程序运行条件编译是在预编译时处理;而条件语句则是在程序运行条件编译是在预编译时处理;而条件语句则是在程序运行条件编译是在预编译时处理;而条件语句则是在程序运行时处理。时处理。时处理。时处理。 条件编译中的条件不可以包含变量名,只能是常量表达式条件编译中的条件不可以包

57、含变量名,只能是常量表达式条件编译中的条件不可以包含变量名,只能是常量表达式条件编译中的条件不可以包含变量名,只能是常量表达式(通常包含宏名),可以不加括号;而条件语句中的条件是条(通常包含宏名),可以不加括号;而条件语句中的条件是条(通常包含宏名),可以不加括号;而条件语句中的条件是条(通常包含宏名),可以不加括号;而条件语句中的条件是条件表达式,可以包含变量或函数等,并且必须加括号。件表达式,可以包含变量或函数等,并且必须加括号。件表达式,可以包含变量或函数等,并且必须加括号。件表达式,可以包含变量或函数等,并且必须加括号。 例如:例如:例如:例如:#define #define N N

58、9 9intint NUM = 9; NUM = 9;#if NUM = 9#if NUM = 9 # #endifendif 错误,错误,错误,错误,NUMNUM是变是变是变是变量。可改为:量。可改为:量。可改为:量。可改为: #if N = 9#if N = 9 语语言言程程序序设设计计教教程程 第第4章章 预预处处理理命命令令C条件编译与分支语句二者之间的差别:条件编译与分支语句二者之间的差别:条件编译与分支语句二者之间的差别:条件编译与分支语句二者之间的差别: 条件编译是将满足编译条件的源程序代码段进行编译生成目标代码,不条件编译是将满足编译条件的源程序代码段进行编译生成目标代码,不条

59、件编译是将满足编译条件的源程序代码段进行编译生成目标代码,不条件编译是将满足编译条件的源程序代码段进行编译生成目标代码,不满足编译条件的程序代码将不进行编译;而分支语句则是不管满足条件的代满足编译条件的程序代码将不进行编译;而分支语句则是不管满足条件的代满足编译条件的程序代码将不进行编译;而分支语句则是不管满足条件的代满足编译条件的程序代码将不进行编译;而分支语句则是不管满足条件的代码,还是不满足条件的代码,都要编译生成目标代码(包括分支语句本身),码,还是不满足条件的代码,都要编译生成目标代码(包括分支语句本身),码,还是不满足条件的代码,都要编译生成目标代码(包括分支语句本身),码,还是不

60、满足条件的代码,都要编译生成目标代码(包括分支语句本身),所以如果用条件语句来代替条件编译命令,程序的目标代码将变长所以如果用条件语句来代替条件编译命令,程序的目标代码将变长所以如果用条件语句来代替条件编译命令,程序的目标代码将变长所以如果用条件语句来代替条件编译命令,程序的目标代码将变长 条件编译命令可以放在所有函数的外部,也可以放在某函数的内部;但分条件编译命令可以放在所有函数的外部,也可以放在某函数的内部;但分条件编译命令可以放在所有函数的外部,也可以放在某函数的内部;但分条件编译命令可以放在所有函数的外部,也可以放在某函数的内部;但分支语句只能出现在某函数内部。支语句只能出现在某函数内

61、部。支语句只能出现在某函数内部。支语句只能出现在某函数内部。11,62911,629字节字节字节字节11,60511,605字节字节字节字节目标文件大小目标文件大小目标文件大小目标文件大小 (BC3.1(BC3.1下)下)下)下)上面红色部分上面红色部分上面红色部分上面红色部分上面红色部分上面红色部分上面红色部分上面红色部分编译代码编译代码编译代码编译代码NUM is 9NUM is 9NUM is 9NUM is 9运行结果运行结果运行结果运行结果 # #endifendif printf(NUMprintf(NUM not is 9n); not is 9n); printf(printf

62、( NUMNUM not is 9n not is 9n ); ); else else #else #else printf(NUMprintf(NUM is 9n); is 9n); printf(NUMprintf(NUM is 9n); is 9n); if (NUM = 9) if (NUM = 9) #if NUM = 9 #if NUM = 9程序代码程序代码程序代码程序代码 void main ( ) void main ( ) void main ( ) void main ( ) #define NUM 9 #define NUM 9 #define NUM 9 #defi

63、ne NUM 9#include #include #include #include 使用分支语句的源程序使用分支语句的源程序使用分支语句的源程序使用分支语句的源程序使用条件编译的源程序使用条件编译的源程序使用条件编译的源程序使用条件编译的源程序语语言言程程序序设设计计教教程程 第第4章章 预预处处理理命命令令C使用条件编译的原因:使用条件编译的原因:使用条件编译的原因:使用条件编译的原因: 便于程序的移植便于程序的移植便于程序的移植便于程序的移植 # #ifdefifdef TURBOC TURBOC /Turbo C/Turbo C独有的内容独有的内容独有的内容独有的内容# #endif

64、endif# #ifdefifdef BORLANDC BORLANDC /Borland C/Borland C独有的内容独有的内容独有的内容独有的内容# #endifendif# #ifdefifdef VISUALC VISUALC /Visual C/Visual C独有的内容独有的内容独有的内容独有的内容# #endifendif如果希望这个程序在如果希望这个程序在如果希望这个程序在如果希望这个程序在Borland Borland C C环境下编译运行,可在程序的环境下编译运行,可在程序的环境下编译运行,可在程序的环境下编译运行,可在程序的前面写上:前面写上:前面写上:前面写上: #

65、define BORLANDC#define BORLANDC如果希望生成如果希望生成如果希望生成如果希望生成Visual CVisual C版本,版本,版本,版本,就在程序前面写上:就在程序前面写上:就在程序前面写上:就在程序前面写上: #define VISUALC#define VISUALC 便于程序调试便于程序调试便于程序调试便于程序调试 #define DEBUG#define DEBUG # #ifdefifdef DEBUG DEBUG printfprintf(); (); / /临时结果临时结果临时结果临时结果# #endifendif程序调试完毕程序调试完毕程序调试完毕程

66、序调试完毕语语言言程程序序设设计计教教程程 第第4章章 预预处处理理命命令令CDosDosDosDos下的编译预处理命令下的编译预处理命令下的编译预处理命令下的编译预处理命令CPP CPP -P-P- filename.cfilename.c1 1、经过预处理后,生成的文件与源文件同名,只是扩展名为、经过预处理后,生成的文件与源文件同名,只是扩展名为、经过预处理后,生成的文件与源文件同名,只是扩展名为、经过预处理后,生成的文件与源文件同名,只是扩展名为I I; ;2 2、其中命令参数、其中命令参数、其中命令参数、其中命令参数-P-P-,作用是在生成的文件中无需源程序名和,作用是在生成的文件中无

67、需源程序名和,作用是在生成的文件中无需源程序名和,作用是在生成的文件中无需源程序名和 行号行号行号行号语语言言程程序序设设计计教教程程 第第4章章 预预处处理理命命令令C本章小结:本章小结:本章小结:本章小结: C C语言的预处理命令都是以语言的预处理命令都是以语言的预处理命令都是以语言的预处理命令都是以“ “#”#”号开头,它们都不是号开头,它们都不是号开头,它们都不是号开头,它们都不是C C语言的语句,语言的语句,语言的语句,语言的语句,是在预编译时处理的。是在预编译时处理的。是在预编译时处理的。是在预编译时处理的。 宏定义分为两种:宏定义分为两种:宏定义分为两种:宏定义分为两种:不带参数

68、的宏定义不带参数的宏定义不带参数的宏定义不带参数的宏定义和和和和带参数的宏定义带参数的宏定义带参数的宏定义带参数的宏定义,进行宏替,进行宏替,进行宏替,进行宏替换时,如果是不带参数的宏则只将与宏名相同的标识符都替换成宏的内换时,如果是不带参数的宏则只将与宏名相同的标识符都替换成宏的内换时,如果是不带参数的宏则只将与宏名相同的标识符都替换成宏的内换时,如果是不带参数的宏则只将与宏名相同的标识符都替换成宏的内容文本,如果是带参数的宏则首先将宏内容文本中的宏参数替换成实参容文本,如果是带参数的宏则首先将宏内容文本中的宏参数替换成实参容文本,如果是带参数的宏则首先将宏内容文本中的宏参数替换成实参容文本

69、,如果是带参数的宏则首先将宏内容文本中的宏参数替换成实参文本,再将这样所得到的宏的实际内容文本替换源程序中的宏标识符。文本,再将这样所得到的宏的实际内容文本替换源程序中的宏标识符。文本,再将这样所得到的宏的实际内容文本替换源程序中的宏标识符。文本,再将这样所得到的宏的实际内容文本替换源程序中的宏标识符。这样就形成了新的源程序,并且预编译器不对宏的内容文本做任何处理。这样就形成了新的源程序,并且预编译器不对宏的内容文本做任何处理。这样就形成了新的源程序,并且预编译器不对宏的内容文本做任何处理。这样就形成了新的源程序,并且预编译器不对宏的内容文本做任何处理。 宏定义时,末尾一般不要加分号。宏定义时

70、,末尾一般不要加分号。宏定义时,末尾一般不要加分号。宏定义时,末尾一般不要加分号。 宏扩展的整体或参数一般要用括号括起来。宏扩展的整体或参数一般要用括号括起来。宏扩展的整体或参数一般要用括号括起来。宏扩展的整体或参数一般要用括号括起来。 文件包含的使用是编写文件包含的使用是编写文件包含的使用是编写文件包含的使用是编写C C语言程序中不可缺少的,我们在引用语言程序中不可缺少的,我们在引用语言程序中不可缺少的,我们在引用语言程序中不可缺少的,我们在引用C C语言语言语言语言库函数时要使用它;另外,我们也可以将平时积累的一些有用的自定义库函数时要使用它;另外,我们也可以将平时积累的一些有用的自定义库

71、函数时要使用它;另外,我们也可以将平时积累的一些有用的自定义库函数时要使用它;另外,我们也可以将平时积累的一些有用的自定义函数做成一个自定义函数库文件,要使用它们时只需采用文件包含将它函数做成一个自定义函数库文件,要使用它们时只需采用文件包含将它函数做成一个自定义函数库文件,要使用它们时只需采用文件包含将它函数做成一个自定义函数库文件,要使用它们时只需采用文件包含将它们引用过来使用就行,这样就减少了编程的工作量。们引用过来使用就行,这样就减少了编程的工作量。们引用过来使用就行,这样就减少了编程的工作量。们引用过来使用就行,这样就减少了编程的工作量。 使用条件编译的主要原因一是便于程序移植,二是

72、方便程序调试。使用条件编译的主要原因一是便于程序移植,二是方便程序调试。使用条件编译的主要原因一是便于程序移植,二是方便程序调试。使用条件编译的主要原因一是便于程序移植,二是方便程序调试。 语语言言程程序序设设计计教教程程 第第4章章 课课堂堂练练习习预预处处理理命命令令C1.执行下列程序执行下列程序#define M(a,b) (a)(b)? (a):(b)main( )int i=10,j=15; printf(“%dn”,10*M(i,j);的结果是?的结果是?150102.下列程序的输出结果是下列程序的输出结果是:#include “stdio.h”#define SQR(x) x*x

73、main()int a,k=3; a=SQR(k+1);printf(“%d”,a);7语语言言程程序序设设计计教教程程 第第4章章 课课堂堂练练习习预预处处理理命命令令C3.下列程序的输出结果是下列程序的输出结果是_?#define Tap(x) 2*x+1main()int a=6,k=2,m=1; a+=Tap(k+m);printf(“%d”,a);124.设有宏定义设有宏定义#define M(x) x0?-1:x= =0?0:1则表达式则表达式”M(3.0)+1”的值是的值是_?A) -1 B)0 C)1 D)2D语语言言程程序序设设计计教教程程 第第4章章 作作业业预预处处理理命

74、命令令C1、已知宏定义如下:已知宏定义如下:#define PR printf#define NL n#define D %d#define D1 DNL若程序中的语句是若程序中的语句是 PR(D1,a);经预处理后展开为;经预处理后展开为_。A) printf(%dn,a); B) printf(%dn,a);C) printf(%d n,a); D) 原语句错误原语句错误 2、已知宏定义已知宏定义#define N 3#define Y(n) (N+1)*n)执行语句执行语句z=2*(N+Y(5+1);后,变量;后,变量z的值是的值是_。A) 42 B) 48 C) 52 D) 出错出错 3、已知宏定义已知宏定义 #define SQ(x) x*x 执行语句执行语句printf(“%d”,10/SQ(3);后的输出结果是;后的输出结果是_。 A) 1 B) 3 C) 9 D) 10

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

最新文档


当前位置:首页 > 高等教育 > 研究生课件

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