第8章C语言编译预处理_第1页
第8章C语言编译预处理_第2页
第8章C语言编译预处理_第3页
第8章C语言编译预处理_第4页
第8章C语言编译预处理_第5页
已阅读5页,还剩23页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第八章 编译预处理n 作用:对源程序编译之前做一些处理,生成扩展C源程序n 种类o 宏定义 #defineo 文件包含 #includeo 条件编译 #if-#else-#endif等n 格式:o “#”开头o 占单独书写行o 语句尾不加分号如 if(x=YES) printf(“correct!n”); else if (x=NO) printf(“error!n”);展开后: if(x=1) printf(“correct!n”); else if (x=0) printf(“error!n”);o 8.1 宏定义n8.1.1不带参数宏定义o 一般形式: #define 宏名 宏体o 功能

2、:用指定标识符(宏名)代替字符序列(宏体)o 宏展开:预编译时,用宏体替换宏名-不作语法检查如 #define YES 1 #define NO 0 #define PI 3.1415926 #define OUT printf(“Hello,World”);宏体可缺省,表示宏名定义过或取消宏体o 定义位置:任意(一般在函数外面)o 作用域:从定义命令到文件结束o #undef可终止宏名作用域 格式: #undef 宏名例 #define YES 1 main() . #undef YES #define YES 0 max() . YES原作用域YES新作用域o 宏定义可嵌套,不能递归例 #

3、define MAX MAX+10 ()o 引号中的内容与宏名相同也不置换例 #define PI 3.14159 printf(“2*PI=%fn”,PI*2);宏展开:printf(“2*PI=%fn”,3.14159*2);o 宏定义中使用必要的括号()例 #define WIDTH 80 #define LENGTH WIDTH+40 var=LENGTH*2;宏展开:var= 80+40 *2;( )( )例 #define WIDTH 80 #define LENGTH WIDTH+40 var=LENGTH*2;宏展开:var= 80+40 *2; 案例分析1(8.1) #def

4、ine PRICE 30main( ) int num,total; num=10; total=num*PRICE; printf(“total=%d”,total);程序运算结果:程序运算结果:total=300当价格发生变化时,只需要修改宏定义,就可以做到一改而全改案例分析2#define PI3.1415926 main() float l,s,r,v; printf(input raDiuS ); scanf(%f,&r); l=2.0*PI*r; s=PI*r*r; v=3.0/4*PI*r*r*r; printf(l=%10.4fnS=%10.4fnv=%10.4fn,l

5、,s,v); 使用宏名代替一个字符串,可以用一个简单的名字来代替一个长的字符串 。减少了程序中重复书写某些字符串的工作里昂,既不易出错,又提高了程序的可移植性。注意: 如果字符串一行内装不下,可以放到下一行,只要在上一行的结尾处放一个反斜杠() 即可。 例如: # define LONG_STING “this is a very long string that is used.”案例分析3# include # define M 3# define N M+1# define NN N*N/2main()printf(“%dn”,NN);printf(“%dn”,5*NN);第一个第一个p

6、rintf的输出为的输出为6 第二个第二个printf输出值为输出值为18 说明:# define 命令出现在程序中函数的外面,宏名的有效范围为定义命令之后到本源文件结束. 课堂练习o 8.1-7)、15)n 8.12带参数宏定义o 一般形式: #define 宏名(参数表) 宏体例 #define S (r) PI*r*r相当于定义了不带参宏S,代表字符串“(r) PI*r*r” o 宏展开:形参用实参换,其它字符保留o 宏体及各形参外一般应加括号()例 #define S(a,b) a*b . area=S(3,2);宏展开: area=3*2;不能加空格例 #define POWER(x

7、) x*x x=4; y=6; z=POWER(x+y);宏展开:z=x+y*x+y;一般写成: #define POWER(x) (x)*(x)宏展开: z=(x+y)*(x+y);(1)程序中宏名后的实参与命令行中宏名后的虚参按位置一一对应。(2)用实参代替字符串中的虚参,注意只是字符串的代换,不含计算过程。(3)把用实参替换的字符串,替换程序中的宏名。例8.3 写出下列程序运行的结果: # define PT 3.5 # define S(x)PT*x*x main() int a=1,b=2; printf(”%4.1fn”,S (a+b)); 案例分析1说明: (1)对带参数的宏的展

8、开只是将语句中的宏名内的实参字符串代替# define命令行中的虚参,不能人为的增加括号和计算功能。 (2)由子宏定义时,宏名与其所代替的字符串之间有一个或一个以上的空格。 #define MAX(x,y) (x)(y)?(x):(y) .main() int a,b,c,d,t; . t=MAX(a+b,c+d); 宏展开:t=(a+b)(c+d)?(a+b):(c+d);int max(int x,int y) return(xy?x:y);main() int a,b,c,d,t; . t=max(a+b,c+d); 例 用宏定义和函数实现同样的功能案例分析2o 带参的宏与函数区别带参宏

9、函数处理过程不分配内存简单的字符置换分配内存先求实参值,再代入形参处理时间编译时程序运行时参数类型无类型问题定义实参,形参类型程序长度变长不变运行速度不占运行时间调用和返回占时间课堂练习1 定义一个带参数的宏,使两个参数的值互换,并编一个程序,输入两个整数作为使用宏时的参数,输出已经交换的两个值。# define SWAP(a,b) t=b;b=a;a=t;main() int a,b,t; printf(“请输入两个整数:”); scanf(“%d,%d”,&a,&b); printf(“n原来得数据为:a=%d,b=%dn”,a,b); SWAP(a,b); printf(

10、“交换结果为:a=%d,b=&dn”,a,b);课堂练习2分析程序定义一个头文件“format.h”: 在该文件中定义三种输出格式用户文件用#include语句将该文件包含起来;好处:避免重复工作;一改而全改;注意:宏定义修改后,序重新进行编译;o 8.2 文件包含n 功能:一个源文件可将另一个源文件的内容全部包含进来n 一般形式: #include “文件名” 或 #include #include “file2.c”file1.cfile2.cfile1.cfile2.cABAn 处理过程:预编译时,用被包含文件的内容取代该预处理命令,再对“包含”后的文件作一个源文件编译 直接按标

11、准目录搜索“” 先在当前目录搜索,再搜索标准目录可指定路径n 被包含文件内容o 源文件(*.c)o 头文件(*.h)宏定义数据结构定义函数说明等n 文件包含可嵌套#include “file2.c”file1.cAfile3.cC#include “file3.c”file2.c Bfile1.cAfile3.cfile2.c文件包含的使用n C语言标准库函数的使用o #includen 自己定义文件o 系统开发时,某单位人员往往使用一组固定的符号常量,可以把这些宏定义组成一个文件,然后每人都可以使用#include命令把这些符号常量包含到自己的程序中,从而避免重复工作;此外可做到一改而全改;

12、案例分析例8.7 头文件应用实例(1)文件print_format.h#define PR printf#define NL “n”#define D “%d”#define D1 D NL#define D2 D D NL #define D3 D D D NL#define D4 D D D D NL#define S “%s”(2)文件file1.c#include”print_format.h”main() int a,b,c,d; char string =“CHINA”; a=1;b=2;c=3,d=4; PR(D1,a); PR(D2,a,b); PR(D3,a,b,c); PR

13、(D4,a,b,c,d); PR(S, sting);8.3 条件编译 C语言也允许有选择的对源程序的某一部分进行编译,这就是“条件编译”。 条件编译有以下三种形式: #ifdef 程序段1 #else 程序段2 #endif#ifndef 程序段1#else 程序段2#endif# if表达式 程序段1# else 程序段2# endif #ifdef 程序段1 #else 程序段2 #endif8.3.1 条件编译语句 1它的功能是:当指定标识符已经被定义过(一般用#define命令定义),则对程序段1进行编译,否则对程序段2进行编译。 案例分析1 条件编译对于提高C源程序的通用性是很有好

14、处的。如果一个C源程序在不同计算机系统上运行,而不同的计算机又有一定的差异(例如,有的机器以16位(2个字节)来存放一个整数,而有的则以32位存放一个整数),这样往往需要对源程序作必要的修改,这就降低了程序的通用性。可以用以下的条件编译来处理:#ifdefCOMPUTER-A#defineINTEGER-SIZE 16#else#defineINTEGER-SIZE 32#endif即如果COMPUTER-A 在前面已被定义过,则编译下面的命令行:#define INTEGER-SIZE 16否则,编译下面的命令行:#define INTEGER-SIZE 32案例分析2 例如,在调试程序时,

15、常常希望输出一些所需的信息,而在调试完成后不再输出这些信息。可以在源程序中插入以下的条件编译段:#ifdef DEBUGprintf(x=%D,y=%D,Z=%Dn,x,y,Z);#endif如果在它的前面有以下命令行:#define DEBUG则在程序运行时输出x、y、Z的值,以便调试时分析。8.3.2 条件编译语句 2#ifndef 程序段1 #else 程序段2 #endif它的功能是:若指定的标识符未被定义则编译程序段1,否则编译程序段2。这种形式的功能和第一种形式的功能相反。 例如: # ifndef LIST printf(x%d,y%d,z%dn,x,y,z); # endif其

16、预处理功能为:如在此之前未对LIST定义,则输出x,y,z 的值。在程序调试时,不对LIST定义,此时输出x,y,z的值,调试结束后,在运行上述程序段之前,加以下面的命令行: # define LIST则不输出x,y,z的值。8.3.3 条件编译语句 3 # if表达式 程序段1 # else 程序段2 # endif 它的功能是:当指定的表达式为真(非零)时.编译程序段1,否则编译程序段2。应用这种条件编译的方法,可以事先给定某一条件:使程序在不同的条件下执行不同的功能。案例分析例8.8用条件编译方法实现以下功能: 输入一行电报文字,可以任选两种输出,一为原文输出;一为将字母变成其下一字母(如a变成b,z变成a,其它字符不变)。用# define命令来控制是否要译成密码。

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论