《C语言课件:第九章预处理命令.ppt》由会员分享,可在线阅读,更多相关《C语言课件:第九章预处理命令.ppt(14页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、第第 9 章章 预处理命令预处理命令9.1 编译预处理编译预处理9.2 “文件包含文件包含”处理处理9.3 条件编译条件编译9.1 编译预处理编译预处理“编译预处理编译预处理”是是 C 与其它高级语言的一个重要区别。与其它高级语言的一个重要区别。宏定义宏定义;文件包含文件包含;条件编译条件编译;1.宏定义宏定义1)不带参数的宏定义不带参数的宏定义用指定的标识符用指定的标识符(宏名宏名)代表一个常量或字符串代表一个常量或字符串:#define 标识符标识符 常量常量/字符串字符串它们是它们是:例例9.1 求正圆锥体的底周长、底面积和它的体积。求正圆锥体的底周长、底面积和它的体积。#define
2、PI 3.1415926 main()float l,s,r,v;scanf(“%f”,&r);l=2.0 PI r;s=PI r r;v=4.0/3 PI r r r;printf(“l=%10.4f ns=%10.4f nv=%10.4f n”,l,s,v);宏名宏名 PI 用大写,行末无分号用大写,行末无分号 宏名的有效范围为该宏定义命令之后至本源文件结束。宏名的有效范围为该宏定义命令之后至本源文件结束。通常,宏定义命令一般写在文件开头或函数之前作通常,宏定义命令一般写在文件开头或函数之前作为该文件的一部分。为该文件的一部分。可以用可以用#undef 命令终止宏定义的作用域。命令终止宏定
3、义的作用域。如:如:#define G 9.8main()进行宏定义时,可以引用已定义的宏名,层层置换。进行宏定义时,可以引用已定义的宏名,层层置换。对程序中用双引号括起来的字符串,即使与宏名相同对程序中用双引号括起来的字符串,即使与宏名相同 也不会被置换。也不会被置换。G 的作用范围的作用范围#undef Gfloat f()2带参数的宏定义带参数的宏定义语句形式语句形式:#define 宏名宏名(形参表形参表)表达式表达式例例9.3#define PI 3.1415926#define S(r)PI r rmain()float a,area;a=3.6;area=S(a);printf(
4、“r=%f narea=%f n”,a,area);area=3.1415926 a a,但不会置换,但不会置换a为为3.6 对带参数的宏定义的置换展开是用对带参数的宏定义的置换展开是用“表达式表达式”对等对等的置的置 换换“形参表形参表”中的参数。上例中的中的参数。上例中的“”是不会被置换的。是不会被置换的。若将若将area=S(a)改写成改写成 area=S(a+2),将置换为将置换为:area=PI a+2 a+2,而不是而不是:area=PI (a+2)(a+2)。若要达到后者之目的,则应将宏定义命令改写为:若要达到后者之目的,则应将宏定义命令改写为:#define S(r)PI (r
5、)(r)宏名与括号之间不得有空格,因为宏名与表达式之间宏名与括号之间不得有空格,因为宏名与表达式之间 的分隔符为空格。的分隔符为空格。如果用如果用#define S (r)PI r r 的的 话,则被置换为话,则被置换为 area=(r)PI r r (a)宏展开并不进行值的传递,即不求表达式的值,也没宏展开并不进行值的传递,即不求表达式的值,也没 有有“返回值返回值”的概念。的概念。宏不存在类型问题,宏名无类型,参数也无类型,表宏不存在类型问题,宏名无类型,参数也无类型,表 达式可以是任何类型。达式可以是任何类型。定义带参数的宏,可以实现一些简单的函数功能。定义带参数的宏,可以实现一些简单的
6、函数功能。如:如:#define MAX(x,y)(x)(y)?(x):(y)main()int a,b,c,t;t=MAX(a+b,c+d);注注:这里的:这里的 t 展开后为展开后为 t=(a+b)(c+d)?(a+b):(c+d)如果第一行写成:如果第一行写成:#define MAX(x,y)xy?x:y则这里的则这里的 t 展开后为展开后为 t=a+bc+d?a+b:c+d因为因为置换展开是用置换展开是用“表达式表达式”对等对等 的置换的置换“形参表形参表”中的参数中的参数9.2 “文件包含文件包含”处理处理 在在C中可以用中可以用#include 命令实现一个文件包含另一命令实现一个
7、文件包含另一个文件。个文件。语句形式语句形式:#include“文件名文件名”例:例:#include“stdio.h”#define N 2#define M N+1#define NUM (M+1)M/2main()int i,n=1;for(i=1;i=NUM;i+)n+;printf(“%2d”,n);printf(“n”);输出结果输出结果:1 2 3 4 5 6 7 8NUM 被代换展开后为:被代换展开后为:(2+1+1)2+1/2 一个一个include命令只能指定一个被包含文件,如果要命令只能指定一个被包含文件,如果要 包含包含 n 个文件,则要用个文件,则要用 n 个个 in
8、clude 命令。命令。如果如果“文件文件1”包含包含“文件文件2”,而,而“文件文件2”又包含又包含“文件文件3”,则可在则可在“文件文件1”中使用两个中使用两个 include 命命 令。令。即即:文件文件file1.c#include“file3.h”#include“file2.h”file3.h 应出现在应出现在 file2.h 之前之前 文件包含可以嵌套。即一个被包含文件中又可以包含文件包含可以嵌套。即一个被包含文件中又可以包含 另一个文件。另一个文件。如如:文件文件file1.c#include“file2.h”文件文件file2.c#include“file3.h”在在#inc
9、lude 命令中,文件名既可用双引命令中,文件名既可用双引“”号也可用号也可用尖括号尖括号括起来。但用双引号更方便系统查找被包含的括起来。但用双引号更方便系统查找被包含的文件。文件。9.3 条件编译条件编译1条件编译的语句形式条件编译的语句形式其作用是:如果其作用是:如果“标识符标识符”已定义,则编译已定义,则编译“程序段程序段1”,否则编译否则编译“程序段程序段2”。1)#ifdef 标识符标识符程序段程序段1#else程序段程序段2#endif “标识符标识符”一般为一般为#define命令所定义。命令所定义。其中的其中的“程序段程序段1”或或“程序段程序段2”可以是命令,也可以是可以是命
10、令,也可以是 语句或语句组。语句或语句组。#else部分可有可无。部分可有可无。所谓所谓“标识符已定义标识符已定义”是无论是无论“标识符标识符”定义为什么内容。定义为什么内容。用条件编译的作用是缩短编译时间,减少目标程序的用条件编译的作用是缩短编译时间,减少目标程序的 长度。长度。例:例:#ifdef IBM_PC#define INTEGER_SIZE 16#else#define INTEGER_SIZE 32#endif其作用是:如果其作用是:如果“标识符标识符”未定义,则编译未定义,则编译“程序段程序段1”,否则编译否则编译“程序段程序段2”。其作用是:当其作用是:当“表达式表达式”值
11、为非值为非0,则编译,则编译“程序段程序段1”,否则编译否则编译“程序段程序段2”。2)#ifndef 标识符标识符程序段程序段1#else程序段程序段2#endif3)#if 表达式表达式程序段程序段1#else程序段程序段2#endif例例 9.7#define LETTER 1main()char str20=“C language”,c;int i;i=0;while(c=stri!=0)i+;#if LETTER if (c=a&c=A&c=Z)c=c+32;#endif printf(“%c”,c);运行结果:运行结果:C LANGUAGE例例2:#define N 2#define M N+1#define NUM 2 M+1main()int i;for(i=1;i(y)?(x):(y)main()int a=5,b=2,c=3,d=3,t;t=MAX(a+b,c+d)10;printf(“%dn”,t);t 的值是多少的值是多少?程序中的程序中的 for 循环执行的次数是多少循环执行的次数是多少?