第7章 编译预处理(课件)-《 C语言程序设计》同步教学(电子工业出版社)

2024-08-10
| 27页
| 126人阅读
| 12人下载
普通

内容正文:

第7章 编译预处理 预处理命令概述 宏定义 文件包含处理 条件编译 7.1 预处理命令概述 C语言程序在编译之前,通常还需要对源文件进行简单的处理,比如文本替换、文件包含、删除部分代码等。在程序编译之前对源文件进行简单加工的过程,就称为预处理。 合理地使用预处理命令会使编写的程序便于阅读、修改移植和调试,也有利于模块化程序设计。 C语言提供的预处理功能主要有3种:宏定义,文件包含和条件编译。 7.2 宏定义 宏定义是用预处理命令#define实现的预处理。 宏定义分为两种形式:带参数的宏定义与不带参数的宏定义。 7.2.1 不带参数的宏定义 一般格式: #define 标识符 字符串 其中标识符就是宏的名字,简称为宏。 如: #define PI 3.1415926 PI是宏名,字符串3.1415926是替换正文。预处理程序将程序中凡以PI作为标识符出现的地方都用3.1415926替换,这种替换称为宏替换,或者宏扩展。 优点:用一个有意义的标识符代替一个字符串,便于记忆,易于修改,提高程序的可移植性 【例1】计算圆的周长和面积的程序。 #define PI 3.1415926 int main( ) { float r,c,area; scanf(“%f”,&r); c=2*PI*r; area=PI * r * r; printf(“C=%.8lf,AREA=%.8lf”,c,area); return 0; } 说明: 宏名一般用大写字母,以便与程序中的变量名或函数名区分。 宏替换是在编译之前进行的,由编译预处理程序完成,不占用程序的运行时间。在替换时,只是作简单的替换,不作语法检查。 宏定义不需要使用语句结束符“;” 。 在进行宏定义时,可以使用已定义过的宏名,即宏定义嵌套形式。 一个宏的作用域是从定义的地方开始到本文件结束。也可以用#undef命令终止宏定义的作用域。 一般情况下,宏定义放在函数开头,所有函数之前。也可以把所有定义语句放在单独一个文件里,再把这个文件包含到你的程序文件中。 【例2】宏嵌套定义。 #define PI 3.1415926 #define R 5 #define S PI*R*R int main( ) { float c=2*PI*R; printf(“C=%f,AREA=%f”,c ,S); return 0; } 【例3】宏定义。 #define M (y*y+3*y) int main(){ int s,y; printf("input a number: "); scanf("%d",&y); s=3*M+4*M+5*M; printf("s=%d ",s); return 0; } 运行时输入3,结果输出:? 216 【例4】宏定义。 #define M y*y+3*y int main(){ int s,y; printf("input a number: "); scanf("%d",&y); s=3*M+4*M+5*M; printf("s=%d ",s); return 0; } 运行时输入3,结果输出:? 135 7.2.2 带参数的宏定义 带参数宏定义的一般形式为: #define 标识符(参数表) 字符串 字符串中应包含有参数表中所指定的参数。 例如: #define MIN(x,y) ((x)<(y)?(x):(y)) 则语句:c=MIN(3,7); 将被替换为语句: c=((3)<(7)?(3):(7)); 【例5】带参数的宏定义。 #define PI 3.1415926 #define S(r) PI*(r)*(r) int main( ) { float c,d,r; scanf(“%f”,&r); c=2*PI*r; d=S(r); printf(“C=%f,AREA=%f”, c ,d); return 0; } 注意:不要写成 #define S (r) P1*(r)*(r) 说明: 在定义宏名时,宏名与带参数的括号之间不应有空格。 在定义宏的命令行中,要注意将字符串及字符串中各个参数用括号括起来。 带参数的宏调用和函数调用非常相似,其主要的区别在于: 带参数的宏替换只是简单的字符串替换,并不进行计算,也不检查参数类型的一致性。 函数调用时,先计算实参表达式的值,再将它的值传给形参,在传递过程中,要检查实参和形参的数据类型是否一致。 【例6】带参数的宏定义。 #define SUM(x,y) x*y int main( ) { int d; d=SUM(3+5,5+5); printf(“d=%d”, d); return 0; } 运行结果: d=33 分析:进行字符串替换. d=3+5*5+5 【例7】带参数的宏定义。 #define SUM(x,y) (x)*(y) int main( ) { int d; d=SUM(3+5,5+5); printf(“d=%d”, d); return 0; } 运行结果:d=80 分析:进行字符串替换. d=(3+5)*(5+5) 注意:带参数的宏中,每一个参数都要用括号括起来,最好在整个表达式外再加括号 #define SUM(x,y) ( (x)*(y) ) 15 程序1: #define SQ(y) y*y int main() { int a=3,sq; sq=160/SQ(a+1); printf("sq=%d ",sq); return 0; } 程序2: #define SQ(y) (y)*(y) int main() { int a=3,sq; sq=160/SQ(a+1); printf("sq=%d ",sq); return 0; } 程序3: #define SQ(y) ((y)*(y)) int main() { int a=3,sq; sq=160/SQ(a+1); printf("sq=%d ",sq); return 0; } 运行结果: 程序1:57 程序2:160 程序3:10 16 7.3 文件包含处理 文件包含处理是指通过#include命令把另外一 个源文件的内容包含到本文件中。 文件包含的命令格式: 格式1: #include <filename> 格式2: #include “filename” 预处理程序在对源程序文件扫描时,如遇到#include命令,则将指定的filename文件内容替换到源文件中的#include命令行中,并放在#include命令行的位置上。 说明: 在程序设计中常常把一些公用性的符号常量、宏、变量和函数的说明等集中起来组成若干文件,使用时,可以根据需要将相关文件包含进来,这样可以避免在多个文件中输入相同的内容,也为程序的可移植性、可修改性提供了良好的条件。 格式1中使用尖括号< >和格式2中使用双引号“ ”的区别在于:用双引号时,预处理程序首先在当前的目录中检索要包含的文件,若找不到,再按系统指定的标准方式检索其它目录。用尖括号时,不检索当前目录而直接按系统规定的标准方式检索文件目录。 【例8】文件包含 /*file1.c*/ #define PI 3.1415926 #define S(r) P1*(r)*(r) #define C(r) 2*PI*(r) #define V(r) 4.0/3.0*P1*(r)*(r)*(r) /*file2.c*/ #define PI 3.1415926 #define S(r) P1*(r)*(r) #define C(r) 2*PI*(r) #define V(r) 4.0/3.0*P1*(r)*(r)*(r) int main() { int r=5; float s1,c1; s1=S(r); c1=C(r); printf(“%f,%f”,s1,c1); return 0; } /*file2.c*/ #include “file1.c” int main() { int r=5; float s1,c1; s1=S(r); c1=C(r); printf(“%f,%f”,s1,c1); return 0; } 编译前 编译后 /*file3.c*/ #include “file2.c” int main() { int r=10; float v1; v1=V(r); printf(“%f”,v1); return 0; } /*file2.c*/ #include “file1.c” int main() { int r=5; float s1,c1; s1=S(r); c1=C(r); printf(“%f,%f”,s1,c1); return 0; } 7.4 条件编译 整个源程序通常情况都需要参加编译,C语言预处理程序具有条件编译的能力。 使用条件编译命令,可以在满足给定条件时对某些语句进行编译,而在不满足条件时对另外一些语句编译,使同一个源程序在不同的条件下产生不同的目标代码文件。 1、#if形式的一般格式: #if <表达式> <程序段1> [#else <程序段2>] #endif 功能: 通过测试表达式的值,若为真,则对程序段1进行编译,否则,编译程序段2。 【例9】 #define X 10 int main() { #if(X-10) printf("X2=%d",X*X); #else printf("X3=%d",X*X*X); #endif return 0; } 运行结果:X3=1000 2、 #ifdef形式一般格式: #ifdef <标识符> <程序段1> [#else <程序段2>] #endif 功能: 是通过判断#ifdef 后面的<标识符>是否被定义过(一般用#define命令定义),若<标识符>已经定义,则条件为真,编译<程序段1>;否则,条件为假,编译<程序段2>。 3、#ifndef形式一般格式: #ifndef <标识符> <程序段1> [#else <程序段2>] #endif 功能: 若#ifndef后面的<标识符>没有被定义,条件为真,编译<程序段1>;否则,条件为假,编译<程序段2>。 本章小结 本章主要介绍编译预处理的三种不同形式:宏定义、文件包含和条件编译。它们是在程序具体编译之前,预先进行处理。使用这些预处理命令可以编写出更易移植、易调试、模块化的程序,从而提高程序的开发效率。 $$

资源预览图

第7章  编译预处理(课件)-《 C语言程序设计》同步教学(电子工业出版社)
1
第7章  编译预处理(课件)-《 C语言程序设计》同步教学(电子工业出版社)
2
第7章  编译预处理(课件)-《 C语言程序设计》同步教学(电子工业出版社)
3
第7章  编译预处理(课件)-《 C语言程序设计》同步教学(电子工业出版社)
4
第7章  编译预处理(课件)-《 C语言程序设计》同步教学(电子工业出版社)
5
第7章  编译预处理(课件)-《 C语言程序设计》同步教学(电子工业出版社)
6
所属专辑
由于学科网是一个信息分享及获取的平台,不确保部分用户上传资料的 来源及知识产权归属。如您发现相关资料侵犯您的合法权益,请联系学科网,我们核实后将及时进行处理。