C++编译预处理.ppt
计算机基础教研室计算机基础教研室计算机基础教研室计算机基础教研室 罗贤缙罗贤缙罗贤缙罗贤缙 Tel:7522324Tel:7522324North China Electric Power UniversityNorth China Electric Power University编译预处理编译预处理 头文件头文件 宏定义宏定义计算机基础教研室计算机基础教研室计算机基础教研室计算机基础教研室 罗贤缙罗贤缙罗贤缙罗贤缙 Tel:7522324Tel:7522324North China Electric Power UniversityNorth China Electric Power University C+中的编译过程分为预处理和正式编中的编译过程分为预处理和正式编译两步,预处理由预处理命令完成。译两步,预处理由预处理命令完成。书写规则书写规则 1、预处理命令以、预处理命令以“#”开头;开头;2、一行只书写一条预处理命令、一行只书写一条预处理命令 3、结束时不使用、结束时不使用“;”l l文件包含文件包含文件包含文件包含#include#includel l宏定义宏定义宏定义宏定义#define#definel l条件编译条件编译条件编译条件编译#if-#else-#if-#else-#endif#endif等等等等计算机基础教研室计算机基础教研室计算机基础教研室计算机基础教研室 罗贤缙罗贤缙罗贤缙罗贤缙 Tel:7522324Tel:7522324North China Electric Power UniversityNorth China Electric Power University一般形式一般形式一般形式一般形式:#include#include 文件名文件名文件名文件名 或或或或#include#include#include#include cpp1.cppcpp1.cppA Aiostream.hiostream.hB Bcpp1.cppcpp1.cppB BA A预编译过程:用被包含文件的内容取代该预处理预编译过程:用被包含文件的内容取代该预处理预编译过程:用被包含文件的内容取代该预处理预编译过程:用被包含文件的内容取代该预处理命令,再对命令,再对命令,再对命令,再对“包含包含包含包含”后的文件作一个源文件编译后的文件作一个源文件编译后的文件作一个源文件编译后的文件作一个源文件编译计算机基础教研室计算机基础教研室计算机基础教研室计算机基础教研室 罗贤缙罗贤缙罗贤缙罗贤缙 Tel:7522324Tel:7522324North China Electric Power UniversityNorth China Electric Power University常见的文件包含命令常见的文件包含命令#include#include 程序使用程序使用程序使用程序使用cincin和和和和coutcout进行输入输出进行输入输出进行输入输出进行输入输出#include#include 程序使用程序使用程序使用程序使用scanfscanf和和和和printfprintf进行输入输出进行输入输出进行输入输出进行输入输出#include#include 程序中使用数学函数,如程序中使用数学函数,如程序中使用数学函数,如程序中使用数学函数,如sin(xsin(x)、sqrt(xsqrt(x)#include#include 程序中使用字符串函数,如程序中使用字符串函数,如程序中使用字符串函数,如程序中使用字符串函数,如strcpystrcpy()()#include#include 与与与与#include#include 连用,控制输连用,控制输连用,控制输连用,控制输出格式出格式出格式出格式计算机基础教研室计算机基础教研室计算机基础教研室计算机基础教研室 罗贤缙罗贤缙罗贤缙罗贤缙 Tel:7522324Tel:7522324North China Electric Power UniversityNorth China Electric Power Universityl不带参数的宏定义不带参数的宏定义不带参数的宏定义不带参数的宏定义用一个指定的标识符来代表一个字符串用一个指定的标识符来代表一个字符串用一个指定的标识符来代表一个字符串用一个指定的标识符来代表一个字符串#definedefine 标识符标识符标识符标识符 字符串字符串字符串字符串宏名宏名宏名宏名宏展开:宏展开:宏展开:宏展开:在预编译时将宏名替换为字符串在预编译时将宏名替换为字符串在预编译时将宏名替换为字符串在预编译时将宏名替换为字符串宏定义命令宏定义命令宏定义命令宏定义命令例:例:例:例:#define PI 3.1415926define PI 3.1415926计算机基础教研室计算机基础教研室计算机基础教研室计算机基础教研室 罗贤缙罗贤缙罗贤缙罗贤缙 Tel:7522324Tel:7522324North China Electric Power UniversityNorth China Electric Power University例例例例:#include#include#define PI 3.1415926#define PI 3.1415926 void main()void main()float l,s,r,v;float l,s,r,v;cinr;cinr;l=2.0*PI*r;l=2.0*PI*r;s=PI*r*r;s=PI*r*r;v=3.0/4*PI*r*r*r;v=3.0/4*PI*r*r*r;coutL=lnS=snV=v;coutL=lnS=snV=v;宏展开宏展开宏展开宏展开l=2.0*3.1415926*r;l=2.0*3.1415926*r;s=3.1415926*r*r;s=3.1415926*r*r;v=3.0/4*3.1415926*r*r*r;v=3.0/4*3.1415926*r*r*r;计算机基础教研室计算机基础教研室计算机基础教研室计算机基础教研室 罗贤缙罗贤缙罗贤缙罗贤缙 Tel:7522324Tel:7522324North China Electric Power UniversityNorth China Electric Power University使用宏定义可减少工作量使用宏定义可减少工作量使用宏定义可减少工作量使用宏定义可减少工作量,提高程序的可以移植性提高程序的可以移植性提高程序的可以移植性提高程序的可以移植性.宏定义只作简单的替换宏定义只作简单的替换宏定义只作简单的替换宏定义只作简单的替换,不作语法检查不作语法检查不作语法检查不作语法检查.宏定义不是语句宏定义不是语句宏定义不是语句宏定义不是语句,不必在行末加分号不必在行末加分号不必在行末加分号不必在行末加分号.#define#define命令出现在函数之外命令出现在函数之外命令出现在函数之外命令出现在函数之外,其有效范围从定其有效范围从定其有效范围从定其有效范围从定义命令之后到本源文件结束义命令之后到本源文件结束义命令之后到本源文件结束义命令之后到本源文件结束.可用可用可用可用#undef undef 命令终止宏定义的作用域命令终止宏定义的作用域命令终止宏定义的作用域命令终止宏定义的作用域.#define G 9.9#define G 9.9void main()void main()#undef G#undef G f1()f1()GG的有效范围的有效范围的有效范围的有效范围宏名一般习惯用大写字母表示宏名一般习惯用大写字母表示宏名一般习惯用大写字母表示宏名一般习惯用大写字母表示,以与变量名相区别以与变量名相区别以与变量名相区别以与变量名相区别.计算机基础教研室计算机基础教研室计算机基础教研室计算机基础教研室 罗贤缙罗贤缙罗贤缙罗贤缙 Tel:7522324Tel:7522324North China Electric Power UniversityNorth China Electric Power University在进行宏定义时在进行宏定义时在进行宏定义时在进行宏定义时,可以引用已定义的宏名可以引用已定义的宏名可以引用已定义的宏名可以引用已定义的宏名,层层替换层层替换层层替换层层替换.例:例:例:例:#include#include#define R 3.0#define R 3.0#define PI 3.1415926#define PI 3.1415926#define L 2*PI*R#define L 2*PI*R#define S L/2*R#define S L/2*R void main()void main()coutcoutL=LL=LnSnS=S;=S;L L 宏展开为宏展开为宏展开为宏展开为:2*3.1415926*3.0:2*3.1415926*3.0S S 宏展开为宏展开为宏展开为宏展开为:2:2*3.1415926*3.03.1415926*3.0/2 /2*3.0*3.0用双引号括起来的字符串内的字符不置换用双引号括起来的字符串内的字符不置换用双引号括起来的字符串内的字符不置换用双引号括起来的字符串内的字符不置换.coutcoutL L=L=Ln nS S=S;=S;不被置换不被置换不被置换不被置换计算机基础教研室计算机基础教研室计算机基础教研室计算机基础教研室 罗贤缙罗贤缙罗贤缙罗贤缙 Tel:7522324Tel:7522324North China Electric Power UniversityNorth China Electric Power University不仅要进行字符串替换不仅要进行字符串替换不仅要进行字符串替换不仅要进行字符串替换,还要对参数替换还要对参数替换还要对参数替换还要对参数替换#define define 宏名宏名宏名宏名(参数表参数表参数表参数表 )字符串字符串字符串字符串包含参数表中的参数包含参数表中的参数包含参数表中的参数包含参数表中的参数字符串字符串字符串字符串如:如:如:如:#define S(a,b)a*b#define S(a,b)a*b area=S(3,2);area=S(3,2);S(a,b)S(a,b)a*ba*bS(3,2)S(3,2)3*2 3*2参参参参数数数数替替替替换换换换6 6l带参数的宏定义带参数的宏定义带参数的宏定义带参数的宏定义计算机基础教研室计算机基础教研室计算机基础教研室计算机基础教研室 罗贤缙罗贤缙罗贤缙罗贤缙 Tel:7522324Tel:7522324North China Electric Power UniversityNorth China Electric Power University#include#include#define PI 3.1415926#define PI 3.1415926#define#define S(rS(r)PI *r *r)PI *r *r void main()void main()float a,area,b;float a,area,b;a=3;b=0.6;a=3;b=0.6;area=S(area=S(a+ba+b););coutcoutr=ar=anareanarea=area;=area;()()()()宏展开为宏展开为宏展开为宏展开为:area=3.1415926*a+b*a+b:area=3.1415926*a+b*a+b显然显然显然显然,此式与原意不符此式与原意不符此式与原意不符此式与原意不符!怎样修改怎样修改怎样修改怎样修改?定义时在形定义时在形定义时在形定义时在形参外加括弧参外加括弧参外加括弧参外加括弧宏展开为宏展开为宏展开为宏展开为:area=3.1415926*:area=3.1415926*(a+ba+b)*(a+ba+b)计算机基础教研室计算机基础教研室计算机基础教研室计算机基础教研室 罗贤缙罗贤缙罗贤缙罗贤缙 Tel:7522324Tel:7522324North China Electric Power UniversityNorth China Electric Power University函数调用是在运行时处理,分配内存;而宏展开在函数调用是在运行时处理,分配内存;而宏展开在函数调用是在运行时处理,分配内存;而宏展开在函数调用是在运行时处理,分配内存;而宏展开在预处理时进行,不分配内存。预处理时进行,不分配内存。预处理时进行,不分配内存。预处理时进行,不分配内存。函数参数有类型问题,而宏不存在类型问题,宏名函数参数有类型问题,而宏不存在类型问题,宏名函数参数有类型问题,而宏不存在类型问题,宏名函数参数有类型问题,而宏不存在类型问题,宏名及其参数无类型。及其参数无类型。及其参数无类型。及其参数无类型。带参宏只进行简单的字符替换,而函数调用则要先带参宏只进行简单的字符替换,而函数调用则要先带参宏只进行简单的字符替换,而函数调用则要先带参宏只进行简单的字符替换,而函数调用则要先求实参值,再进行值传递。求实参值,再进行值传递。求实参值,再进行值传递。求实参值,再进行值传递。int add(int x,int y)int add(int x,int y)return(x+yreturn(x+y););add(1,2);add(1,2);add(1.5,1.6);add(1.5,1.6);#define add(x,y)(x)+(y)define add(x,y)(x)+(y)add(1,2);add(1,2);add(1.5,1.6);add(1.5,1.6);宏展开后源程序增长,而函数调用则不会。宏展开后源程序增长,而函数调用则不会。宏展开后源程序增长,而函数调用则不会。宏展开后源程序增长,而函数调用则不会。函数调用占运行时间,而宏替换只占编译时间,函数调用占运行时间,而宏替换只占编译时间,函数调用占运行时间,而宏替换只占编译时间,函数调用占运行时间,而宏替换只占编译时间,后者时间效益高。后者时间效益高。后者时间效益高。后者时间效益高。计算机基础教研室计算机基础教研室计算机基础教研室计算机基础教研室 罗贤缙罗贤缙罗贤缙罗贤缙 Tel:7522324Tel:7522324North China Electric Power UniversityNorth China Electric Power University