C语言程序设计李鸿编译预处理.doc_第1页
C语言程序设计李鸿编译预处理.doc_第2页
C语言程序设计李鸿编译预处理.doc_第3页
C语言程序设计李鸿编译预处理.doc_第4页
C语言程序设计李鸿编译预处理.doc_第5页
全文预览已结束

下载本文档

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

文档简介

C程序设计 备课笔记第九章 编译预处理编译指令(编译预处理指令):C源程序除了包含程序命令(语句)外,还可以使用各种编译指令(编译预处理指令)。编译指令(编译预处理指令)是给编译器的工作指令。这些编译指令通知编译器在编译工作开始之前对源程序进行某些处理。编译指令都是用“#”引导。编译预处理:编译前根据编译预处理指令对源程序的一些处理工作。C语言编译预处理主要包括宏定义、文件包含、条件编译。编译工作实际分为两个阶段:编译预处理、编译。广义的编译工作还包括连接。宏定义文件包含条件编译编译预处理连接编译9、1 宏定义宏定义:用标识符来代表一个字符串(给字符串取个名字)。C语言用“#define”进行宏定义。C编译系统在编译前将这些标识符替换成所定义的字符串。宏定义分为不带参数的宏定义和带参数宏定义。#define 标识符 字符串9、1、1 不带参数宏定义(简单替换)1、不带参数宏定义格式: 其中:标识符-宏名。2、宏调用:在程序中用宏名替代字符串。3、宏展开:编译预处理时将字符串替换宏名的过程,称为宏展开。#define PI 3.14main() float r=3,s,c;宏调用 s=PI*r*r; c=2*PI*r; printf(r,s,c);main()宏展开 float r=3,s,c; s=3.14*r*r; c=2*3.14*r; printf(r,s,c);宏定义,其中PI宏名:代表3.14例如:说明:(1) 宏名遵循标识符规定,习惯用大写字母表示,以便区别普通的变量。(2) #define之间不留空格,宏名两侧空格(至少一个)分隔。(3) 宏定义字符串不要以分号结束,否则分号也作为字符串的一部分参加展开。从这点上看宏展开实际上是简单的替换。例如:#define PI 3.14; 展开为s=3.14;*r*r;(导致编译错误)(4) 宏定义用宏名代替一个字符串,并不管它的数据类型是什么,也不管宏展开后的词法和语法的正确性,只是简单的替换。是否正确,编译时由编译器判断。例如:#define PI 3.I4 照样进行宏展开(替换),是否正确,由编译器来判断。(5) #define宏定义宏名的作用范围从定义命令开始直到本源程序文件结束。可以通过#undef终止宏名的作用域。#define E 2.71828宏名E的有效范围,代表串2.71828main() fun(); printf(“%f”,E);#undef E宏名E的有效范围,代表”abc”#define E “abc”fun() char *s=E; printf(“%sn”,s); #deine PI 3.14#define R 3.0#define L 2*PI*R#define S PI*R*Rmain() printf(“L=%f,S=%f”,L,S);(6) 宏定义中,可以出现已经定义的宏名,还可以层层置换。(7) 宏名出现在双引号“”括起来的字符串中时,将不会产生宏替换。(因为出现在字符串中的任何字符都作为字符串的组成部分)(8) 宏定义是预处理指令,与定义变量不同,它只是进行简单的字符串替换,不分配内存。(9) 使用宏的优点:l 程序中的常量可以用有意义的符号代替,程序更加清晰,容易理解(易读)。l 常量值改变时,不要在整个程序中查找,修改,只要改变宏定义就可以。比如,提高PI精度值。l 带参数宏定义比函数调用具有更高的时间效率,因为相当于代码的直接嵌入。(空间效率:多次调用占用空间较多,一次调用没有什么影响)。9、1、2 带参数宏定义类似函数头,但是没有类型说明,参数也不要类型说明。#define 宏名(参数表) 字符串带参数宏定义不只是进行简单的字符串替换,还要进行参数替换。1、 带参数宏定义的格式:例如:#define S(a,b) a*b其中S-宏名,a,b是形式参数。程序调用S(3,2)时,把实参3,2分别代替形参a,b。area=S(3,2); = area=3*2;2、 带参数宏定义展开规则:在程序中如果有带实参的宏定义,则按照#define命令行中指定的“字符串”从左到右进行置换(扫描置换)。如果串中包含宏定义中的形参,则将程序中相应的实参代替形参,其它字符原样保留,形成了替换后的字符串。注意:还是一个字符串的替换过程,只是将形参部分的字符串用相应的实参字符串替换。宏展开:a,b用i,j替换,其它照抄例9-1:用带参数宏定义表示两数中的较大数#define MAX(a,b) (ab)?a:bmain() int i=15,j=20; printf(“MAX=%dn”,MAX(i,j);= printf(“MAX=%dn”,(ij)?i:j);注意:(1)正因为带参宏定义本质还是简单字符替换(除了参数替换),所以容易发生错误。例如:#define S(a,b) a*b程序中area=S(a+b,c+d);=area=a+b*c+d;明显和我们的意图不同。假如:宏定义的字符串中的形参用()括号括起来,即:#define S(a,b) (a)*(b)此时程序中:area=S(a+b,c+d);=area=(a+b)*(c+d);符合我们的意图。为了避免出错,建议将宏定义“字符串”中的所有形参用括号()括起来。以后,替换时括号作为一般字符原样照抄,这样用实参替换时,实参就被括号括起来作为整体。不至于发生类似错误。(2)定义带参数宏时还应该注意宏名与参数表之间不能有空格。有空格就变成了不带参数的宏定义。如:#define S (r) PI*r*r area=S(3.0); = area=(r) PI*r*r(3.0);(3)带参数的宏定义在程序中使用时,它的形式及特性与函数相似,但本质完全不同。区别在下面几个方面:l 函数调用,在程序运行时,先求表达式的值,然后将值传递给形参;带参宏展开只在编译时进行的简单字符置换。l 函数调用是在程序运行时处理的,在堆栈中给形参分配临时的内存单元;宏展开是在编译时进行,展开时不可能给形参分配内存,也不进行“值传递”,也没有“返回值”。l 函数的形参要定义类型,且要求形参、实参类型一致。宏不存在参数类型问题。如:程序中可以MAX(3,5)也可以MAX(3.4,9.2)(4)许多问题可以用函数也可以用带参数的宏定义。(5)宏占用的是编译时间,函数调用占用的是运行时间。在多次调用时,宏使得程序变长,而函数调用不明显。例9-3:计算三角形面积。(使用带参数宏定义)作业:(1)将S(a,b,c)改为S(a1,b1,c1);AREA(a,b,c)改为AREA(a2,b2,c2).将main()中a,b,c改为i,j,k重新写9-3程序。(2)对最后printf进行宏展开(分两步走)。9、2 文件包含文件包含:一个C源文件可以使用文件包含命令将另外一个C源文件的全部内容包含进来。#include “文件名”或#include 格式:AB#include “file2.c”AB file1.c file2.c file1.c说明:(1) 被包含的文件常常被称为“头文件”(#include一般写在模块的开头)。头文件常常以“.h”为扩展名(也可以用其它的扩展名,.h只是习惯或风格)。(2) 一条#include只能包含一个头文件,如果要包含多个头文件,使用多条#include命令。(3) 被包含的头文件可以用“”括起来,也可以用括起来。区别在于:先在C系统目录中查找头文件,“”先在用户当前目录查找头文件。习惯上,用户头文件一般在用户目录下,所以常常用“”;系统库函数的头文件一般在系统指定目录下,所以常常用。(4) 头文件的应用(补充)。在多模块应用程序的开发上,经常使用头文件组织程序模块。l 头文件成为共享源代码的手段之一。程序员可以将

温馨提示

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

评论

0/150

提交评论