(6.17)--补充课件第11讲-编译预处理.ppt
《(6.17)--补充课件第11讲-编译预处理.ppt》由会员分享,可在线阅读,更多相关《(6.17)--补充课件第11讲-编译预处理.ppt(57页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、第十一讲第十一讲编译预处理编译预处理C语言程序设计语言程序设计 The C Programming Language2C语言程序设计语言程序设计 温州理工学院温州理工学院 2第十讲编译预处理第十讲编译预处理概述概述宏定义宏定义“文件包含文件包含”处理处理条件编译条件编译程序应用举例程序应用举例小结小结参考书目及网络资源参考书目及网络资源讨论时间讨论时间3C语言程序设计语言程序设计 温州理工学院温州理工学院 3第十一讲编译预处理第十一讲编译预处理概述概述宏定义宏定义“文件包含文件包含”处理处理条件编译条件编译程序应用举例程序应用举例小结小结参考书目及网络资源参考书目及网络资源讨论时间讨论时间4C
2、语言程序设计语言程序设计 温州理工学院温州理工学院 4概述概述C语言与其他高级语言的一个重要区别是可以语言与其他高级语言的一个重要区别是可以使用预处理命令和具有使用预处理命令和具有预处理预处理的功能。的功能。ANSI C标准规定可以在标准规定可以在C源程序中加入一些源程序中加入一些“预处理命令预处理命令”,以改进程序设计环境,提高编,以改进程序设计环境,提高编程效率。程效率。预处理命令是由预处理命令是由ANSI C统一规定的,但是它不统一规定的,但是它不是是C语言本身的组成部分,不能直接对它们进语言本身的组成部分,不能直接对它们进行编译(因为编译程序不能识别它们)。必须行编译(因为编译程序不能
3、识别它们)。必须在对程序进行通常的编译之前,先对程序中这在对程序进行通常的编译之前,先对程序中这些特殊的命令进行些特殊的命令进行“预处理预处理”5C语言程序设计语言程序设计 温州理工学院温州理工学院 5概述概述经过预处理后程序可由编译程序对预处理后的经过预处理后程序可由编译程序对预处理后的源程序进行通常的编译处理,得到可供执行的源程序进行通常的编译处理,得到可供执行的目标代码。目标代码。所谓所谓预处理预处理是指在进行编译的第一遍扫描是指在进行编译的第一遍扫描(词法词法扫描和语法分析扫描和语法分析)之前所作的工作。之前所作的工作。预处理是预处理是C语言的一个重要功能,它由预处理语言的一个重要功能
4、,它由预处理程序负责完成。当对一个源文件进行编译时,程序负责完成。当对一个源文件进行编译时,系统将自动引用预处理程序对源程序中的预处系统将自动引用预处理程序对源程序中的预处理部分作处理,处理完毕自动进入对源程序的理部分作处理,处理完毕自动进入对源程序的编译。编译。6C语言程序设计语言程序设计 温州理工学院温州理工学院 6概述概述(contd)C语言提供了多种预处理功能,如宏定义、文语言提供了多种预处理功能,如宏定义、文件包含、条件编译等。合理地使用预处理功能件包含、条件编译等。合理地使用预处理功能编写的程序便于阅读、修改、移植和调试,也编写的程序便于阅读、修改、移植和调试,也有利于模块化程序设
5、计。有利于模块化程序设计。7C语言程序设计语言程序设计 温州理工学院温州理工学院 7概述概述(contd)C提供的预处理功能主要有以下三种:提供的预处理功能主要有以下三种:宏定义宏定义文件包含文件包含条件编译条件编译这些功能分别用宏定义命令、文件包含命令、这些功能分别用宏定义命令、文件包含命令、条件编译命令来实现。为了与条件编译命令来实现。为了与一般一般C语句语句相区相区别,这些命令以符号别,这些命令以符号“”开头。例如:开头。例如:#define#include8C语言程序设计语言程序设计 温州理工学院温州理工学院 8第十一讲编译预处理第十一讲编译预处理概述概述宏定义宏定义“文件包含文件包含
6、”处理处理条件编译条件编译程序应用举例程序应用举例小结小结参考书目及网络资源参考书目及网络资源讨论时间讨论时间9C语言程序设计语言程序设计 温州理工学院温州理工学院 9宏定义宏定义在在C言言源程序中允许用一个标识符来表示一个字符源程序中允许用一个标识符来表示一个字符串,称为串,称为“宏宏”。被定义为被定义为“宏宏”的标识符称为的标识符称为“宏名宏名”。在编译。在编译预处理时,对程序中所有出现的预处理时,对程序中所有出现的“宏名宏名”,都用,都用宏定义中的字符串去代换,这称为宏定义中的字符串去代换,这称为“宏代换宏代换”或或“宏展开宏展开”。宏是由源程序中的宏定义命令宏是由源程序中的宏定义命令#
7、define来定义的。来定义的。宏代换是由预处理程序自动完成的。宏代换是由预处理程序自动完成的。在在C语言中,语言中,“宏宏”分为两种分为两种:无参宏定义无参宏定义带参宏定义带参宏定义10C语言程序设计语言程序设计 温州理工学院温州理工学院 10无参宏定义无参宏定义无参宏定义无参宏定义一般形式:一般形式:#define 标识符标识符 字符串字符串其中的其中的“#”表示这是一条预处理命令。表示这是一条预处理命令。凡是以凡是以“#”开头的均为预处理命令。开头的均为预处理命令。“define”为宏定义命令。为宏定义命令。“标识符标识符”为所定为所定义的宏名。义的宏名。“字符串字符串”可以是常数、表达
8、式、可以是常数、表达式、格式串等。格式串等。符号常量的定义就是一种无参宏定义。此外,符号常量的定义就是一种无参宏定义。此外,常对程序中反复使用的表达式进行宏定义。常对程序中反复使用的表达式进行宏定义。例如:例如:#define M(y*y+3*y)11C语言程序设计语言程序设计 温州理工学院温州理工学院 11无参宏定义无参宏定义在在s=3*M+4*M+5*M 中作了宏调用。在预处理时中作了宏调用。在预处理时经宏展开后该语句变为:经宏展开后该语句变为:s=3*(y*y+3*y)+4*(y*y+3*y)+5*(y*y+3*y);但要注意的是,在宏定义中表达式但要注意的是,在宏定义中表达式(y*y+
9、3*y)两边两边的括号不能少。否则会发生错误。的括号不能少。否则会发生错误。#define M(y*y+3*y)main()int s,y;printf(“Input a number:);scanf(%d,&y);s=3*M+4*M+5*M;printf(s=%dn,s);12C语言程序设计语言程序设计 温州理工学院温州理工学院 12宏定义宏定义(contd)标识符(宏名)命名,遵守标识符(宏名)命名,遵守C语言标识符的命名规则。为语言标识符的命名规则。为便于与一般变量区别,宏名常采用大写字母。便于与一般变量区别,宏名常采用大写字母。宏定义允许嵌套,在宏定义的字符串中可以使用已经定义宏定义允
10、许嵌套,在宏定义的字符串中可以使用已经定义的宏名。在宏展开时由预处理程序层层代换。的宏名。在宏展开时由预处理程序层层代换。如有定义:如有定义:#define PI 3.1415926#define S PI*r*r /*PI是已定义的宏名是已定义的宏名*/在编译预处理时,语句在编译预处理时,语句printf(“The Area=%lfn”,S);经宏代换后变为:经宏代换后变为:printf(The Area=%lfn,3.1415926*r*r);13C语言程序设计语言程序设计 温州理工学院温州理工学院 13宏定义宏定义(contd)宏定义是用宏名代表字符串,仅作简单置换,不宏定义是用宏名代表
11、字符串,仅作简单置换,不分配内存空间,编译预处理时不检查语法。只有分配内存空间,编译预处理时不检查语法。只有在源程序被宏展开后,进行编译时才作语法检查。在源程序被宏展开后,进行编译时才作语法检查。下列的宏定义都不可取:下列的宏定义都不可取:#define PI =3.1415926535/*多了等号多了等号*/#define PI 3.1415926535;/*多了分号多了分号*/上述宏定义对于同一个语句:上述宏定义对于同一个语句:s=PI*r*r;宏展开后分别为:宏展开后分别为:s=3.1415926535*r*r;s=3.1415926535;*r*r;14C语言程序设计语言程序设计 温州
12、理工学院温州理工学院 14宏定义宏定义(contd)宏替换只对单独的宏名单词进行,对于括在引宏替换只对单独的宏名单词进行,对于括在引号中的字符串不起作用。若有宏定义:号中的字符串不起作用。若有宏定义:#define MAX 500 对于下列语句:对于下列语句:int MAXICOAT=10;/*MAX不是独立单词,不不是独立单词,不替换替换*/printf(“MAX=”,MAX);/*只有后面的要替换只有后面的要替换*/15C语言程序设计语言程序设计 温州理工学院温州理工学院 15#define MAX 500#undef MAX 宏定义宏定义(contd)宏定义必须写在函数之外,宏名的有效范
13、围为宏定义必须写在函数之外,宏名的有效范围为定义命令之后到该源文件结束,也可以使用定义命令之后到该源文件结束,也可以使用#undef 命令来提前终止宏名的作用域。命令来提前终止宏名的作用域。宏名宏名MAX的有效范围的有效范围宏名宏名MAX在此处无效在此处无效16C语言程序设计语言程序设计 温州理工学院温州理工学院 16宏定义使用说明宏定义使用说明宏定义是用宏名来表示一个字符串,在宏展开时宏定义是用宏名来表示一个字符串,在宏展开时又以该字符串取代宏名,这只是一种简单的代换,又以该字符串取代宏名,这只是一种简单的代换,字符串中可以含任何字符,可以是常数,也可以字符串中可以含任何字符,可以是常数,也
14、可以是表达式,预处理程序对它不作任何检查。如有是表达式,预处理程序对它不作任何检查。如有错误,只能在编译已被宏展开后的源程序时发现。错误,只能在编译已被宏展开后的源程序时发现。宏定义不是说明或语句,在行末不必加分号,如宏定义不是说明或语句,在行末不必加分号,如加上分号则连分号也一起置换。加上分号则连分号也一起置换。宏定义必须写在函数之外,其作用域为宏定义命宏定义必须写在函数之外,其作用域为宏定义命令起到源程序结束。如要终止其作用域可使用令起到源程序结束。如要终止其作用域可使用#undef 命令。命令。17C语言程序设计语言程序设计 温州理工学院温州理工学院 17宏定义使用说明宏定义使用说明要终
15、止宏的作用域可使用要终止宏的作用域可使用#undef 命令。命令。#define PI 3.14159main()#undef PIf1()#undef 命令终止命令终止了了PI作用域,因此作用域,因此这里这里PI 只在只在main 函函数中有效,在数中有效,在f1()中中则无效。则无效。18C语言程序设计语言程序设计 温州理工学院温州理工学院 18宏定义使用说明宏定义使用说明宏名在源程序中若用引号括起来,则预处理程序不对宏名在源程序中若用引号括起来,则预处理程序不对其作宏代换。如下例中定义宏名其作宏代换。如下例中定义宏名OK 表示表示100,但在,但在printf 语句中语句中OK 被引号括
16、起来,因此不作宏代换。被引号括起来,因此不作宏代换。宏定义允许嵌套,在宏定义的字符串中可以使用已经宏定义允许嵌套,在宏定义的字符串中可以使用已经定义的宏名。在宏展开时由预处理程序层层代换。定义的宏名。在宏展开时由预处理程序层层代换。#define PI 3.1415926#define S PI*y*y/*PI 是已定义的宏名是已定义的宏名*/#define OK 100main()printf(OK);19C语言程序设计语言程序设计 温州理工学院温州理工学院 19宏定义使用说明宏定义使用说明对对“输出格式输出格式”作宏定义,可以减少书写麻烦。作宏定义,可以减少书写麻烦。#define P p
17、rintf#define D%dn#define F%fnmain()int a=5,c=8,e=11;float b=3.8,d=9.7,f=21.08;P(D F,a,b);P(D F,c,d);P(D F,e,f);getch();20C语言程序设计语言程序设计 温州理工学院温州理工学院 20宏定义使用说明宏定义使用说明习惯上宏名用大写字母表示,以便于与变量区别。但习惯上宏名用大写字母表示,以便于与变量区别。但也允许用小写字母。也允许用小写字母。可用宏定义表示数据类型,使书写方便。例如:可用宏定义表示数据类型,使书写方便。例如:#define STU struct stu。在程序中可用。
18、在程序中可用STU 作变量说作变量说明:明:STU body5,*p;宏定义表示数据类型和宏定义表示数据类型和typedef定义数据说明符:定义数据说明符:宏定义只是宏定义只是简单的字符串代换简单的字符串代换,是在预处理完成,是在预处理完成的的;而而typedef是在编译时处理的,它是在编译时处理的,它不是作简单的代不是作简单的代换换,而是对类型说明符重新命名。被命名的标识符,而是对类型说明符重新命名。被命名的标识符具有类型定义说明的功能。具有类型定义说明的功能。21C语言程序设计语言程序设计 温州理工学院温州理工学院 21#define vs.typedef两者形相似,两者形相似,但在功能上
19、却不相同。但在功能上却不相同。PIN1 a,b;在宏代换后变成在宏代换后变成:int*a,b;表示表示a是指向整是指向整型的指针变量,而型的指针变量,而b是整型变量。是整型变量。PIN2 a,b;表示表示a、b都是指向整型的指针变量。因都是指向整型的指针变量。因为为PIN2是一个类型说明符。是一个类型说明符。由这个例子可见,宏定义虽然也可表示数据类型,由这个例子可见,宏定义虽然也可表示数据类型,但毕竟是作字符代换。在使用时要分外小心,以但毕竟是作字符代换。在使用时要分外小心,以避出错。避出错。#define PIN1 int*typedef(int*)PIN2;22C语言程序设计语言程序设计
20、温州理工学院温州理工学院 22带参宏定义带参宏定义C语言语言允许宏带有参数。在宏定义中的参数称允许宏带有参数。在宏定义中的参数称为形式参数,在宏调用中的参数称为实际参数。为形式参数,在宏调用中的参数称为实际参数。对带参数的宏,在调用中,不仅要宏展开,而对带参数的宏,在调用中,不仅要宏展开,而且要用实参去代换形参。且要用实参去代换形参。带参宏定义的一般形式为:带参宏定义的一般形式为:#define 宏名宏名(形参表形参表)字符串字符串在字符串中含有各个形参在字符串中含有各个形参。23C语言程序设计语言程序设计 温州理工学院温州理工学院 23带参宏定义带参宏定义带带参宏调用的一般形式为:参宏调用的
21、一般形式为:宏名宏名(实参表实参表);例如:例如:#define M(y)y*y+3*y/*宏定义宏定义*/k=M(5);/*宏调用宏调用*/在宏调用时,用实参在宏调用时,用实参5 去代替形参去代替形参y,经预处理宏,经预处理宏展开后的语句为:展开后的语句为:k=5*5+3*524C语言程序设计语言程序设计 温州理工学院温州理工学院 24带参宏定义带参宏定义带参宏定义带参宏定义#define MAX(a,b)(ab)?a:bmain()int x,y,max;printf(input two numbers:);scanf(%d%d,&x,&y);max=MAX(x,y);printf(max
22、=%dn,max);用宏名用宏名MAX 表示条表示条件表达式件表达式(ab)?a:b,形参形参a,b 均出现在条件均出现在条件表达式中。表达式中。max=MAX(x,y)为宏为宏调用,实参调用,实参x,y,将代,将代换形参换形参a,b。宏展开后。宏展开后该语句为:该语句为:max=(xy)?x:y;25C语言程序设计语言程序设计 温州理工学院温州理工学院 25带参的宏定义使用说明带参的宏定义使用说明带参宏定义中,宏名和形参表之间带参宏定义中,宏名和形参表之间不能有空格不能有空格出现。出现。在宏定义中的形参是标识符,而宏调用中的实在宏定义中的形参是标识符,而宏调用中的实参可以是表达式。参可以是表
23、达式。#define MAX(a,b)(ab)?a:b不能写成:不能写成:#define MAX(a,b)(ab)?a:b26C语言程序设计语言程序设计 温州理工学院温州理工学院 26带参的宏定义使用说明带参的宏定义使用说明在带参宏定义中,形式参数不分配内存单元,在带参宏定义中,形式参数不分配内存单元,因此不必作类型定义。而宏调用中的实参有具因此不必作类型定义。而宏调用中的实参有具体的值。要用它们去代换形参,因此必须作类体的值。要用它们去代换形参,因此必须作类型说明。型说明。在函数中,形参和实参是两个不同的量,各有在函数中,形参和实参是两个不同的量,各有自己的作用域,调用时要把实参值赋予形参,
24、自己的作用域,调用时要把实参值赋予形参,进行进行“值传递值传递”。而在带参宏中,只是符号代。而在带参宏中,只是符号代换,不存在值传递的问题。换,不存在值传递的问题。27C语言程序设计语言程序设计 温州理工学院温州理工学院 27带参的宏定义使用说明带参的宏定义使用说明#define SQ(y)(y)*(y)main()int a,sq;printf(input a number:);scanf(%d,&a);sq=SQ(a+1);printf(sq=%dn,sq);getch();宏定义,形参为宏定义,形参为y。宏。宏调用中实参为调用中实参为a+1,是一,是一个表达式,在宏展开时得个表达式,在宏
25、展开时得到如下语句:到如下语句:sq=(a+1)*(a+1);这与函数的调用是不同这与函数的调用是不同的,函数调用时要把实参的,函数调用时要把实参表达式的值求出来再赋予表达式的值求出来再赋予形参。而宏代换中对实参形参。而宏代换中对实参表达式不作计算直接地照表达式不作计算直接地照原样代换。原样代换。28C语言程序设计语言程序设计 温州理工学院温州理工学院 28带参的宏与带参函数不同带参的宏与带参函数不同SQ(int y)return(y)*(y);main()int i=1;while(i=5)printf(%dn,SQ(i+);getch();#define SQ(y)(y)*(y)main(
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 6.17 补充 课件 11 编译 预处理
限制150内