• 1. 第6章 编译预处理 杨章伟 e-mail:yang505412@163.com
  • 2. 课程内容安排预处理命令 宏 文件包含 条件编译 其他命令 小结 习题
  • 3. 预处理命令 简单来说,预处理就是对源文件进行编译前,先对预处理部分进行处理,然后对处理后的代码进行编译。这样做的好处是,经过处理后的代码,将会变得很精短。为让用户更好地使用预处理,C++提供了丰富的预处理命令,主要包括如下几种:#define、/#error、#if、#else、#elif、#endif、#ifdef、#ifndef、#undef、#line和#pragma。 由上述命令读者可以看出,每个预处理指令均带有符号“#”。简单来说,上面的这些预处理命令可以划分为文件包含、条件编译、布局控制和宏替换4个大类 。
  • 4. 宏 宏(macro)是程序设计语言中使用较为广泛的一个概念,简单来说,宏是一种以相同的源语言执行预定义指令序列的指令。在C++中,通过宏的使用,可以将一个表达式定义成宏,并在C++的源程序中随意调用。 在编译预处理时,对程序中所有出现的宏名,都用宏定义中的字符串去代换,这称为宏代换或宏展开。
  • 5. 宏定义 宏定义是由源程序中的宏定义命令完成的,宏代换是由预处理程序自动完成的。在C++中,宏分为有参数和无参数两种。 不带参数的宏也称为无参宏,其宏名后不带参数,定义的一般形式为: #define 标识符 字符串 带参数的宏定义的一般形式为: #define 宏名(形参表) 字符串
  • 6. 取消宏 由于宏定义的作用域是整个源程序,在一些应用中不需要其覆盖整个程序,因此就需要终止其作用域,C++中终止其作用域的命令为# undef。如果要求宏定义只在一个函数中起作用,就可以在函数定义之前定义宏,在函数结束后结束宏。 宏嵌套 在宏定义中,读者还需要注意的是,宏定义允许嵌套,即在宏定义的字符串中可以使用已经定义的宏名,在宏展开时由预处理程序层层代换。
  • 7. 内联函数 内联函数也称为内嵌函数,当在一个函数的定义或声明前加上关键字inline则就把该函数定义为内联函数,它主要用于解决程序的运行效率。 计算机在执行一般函数的调用时,无论该函数多么简单或复杂,都要经过参数传递、执行函数体和返回等操作,这些操作都需要一定的时间。若把一个函数定义为内联函数后,在程序编译阶段,编译器就会在每次调用该函数的地方都直接替换为该函数体中的代码,由此省去函数的调用、相应地保存现场、参数传递和返回操作等所需的时间,从而加快整个程序的执行速度。
  • 8. 宏与函数的区别 由于宏也可以带参数,而且带参数的宏与带参数的函数的写法和调用都很相似,但是其存在本质上的不同。前面已经提到过,函数调用时要把实参表达式的值求出来再赋予形参,而宏代换中对实参表达式不作计算直接地代换。这导致了即使把同一表达式用函数处理与用宏处理,两者的结果有可能是不同的。 【范例6-11】宏的定义和调用与函数的定义和调用的比较。该范例定义了一个带参宏和带参函数,其函数名为SQ,形参为Y,函数体表达式为((y)*(y)),而宏定义也定义字符串为((y)*(y))
  • 9. 文件包含 文件包含是C++预处理程序的另一个重要功能。文件包含是指一个C++源程序中将另一个C++源程序包含进来,通过#include预处理指令实现。 C++中,#include被称为文件包含命令,其意义是把尖括号< >或引号“”内指定的文件包含到本程序来,成为本程序的一部分。被包含的文件通常是由系统提供的,其扩展名为.h。因此也称为头文件或首部文件。 #include #include "iostream.h"
  • 10. 条件编译 预处理程序除了提供上面介绍的宏定义和文件包含功能,其还提供了条件编译的功能。条件编译可以按不同的条件去编译不同的程序部分,因而产生不同的目标代码文件。这对于程序的移植和调试是很有用的。 #ifdef形式:如果标识符已被#define命令定义过,对程序段1进行编译,否则对程序段2进行编译。 #ifndef形式 :如果标识符未被#define命令定义过,则对程序段1进行编译,否则对程序段2进行编译。 #if形式 :如常量表达式的值为真(非0),则对程序段1进行编译,否则对程序段2进行编译。
  • 11. 其他命令 #error命令 :C++中,预处理程序中的#error指令用于程序的调试,在编译中遇到#error指令就停止编译。 #line命令 :#line命令用于控制行号,其一般在发布错误和警告信息时使用。当用户在编译一段程序的时候,如果有错误发生,编译器会在错误前面显示出错文件的名称及文件中的第几行发生错误。指令#line可以实现这个功能,也就是说,当出错时显示文件中的行数及希望显示的文件名。
  • 12. 本章主要介绍了C++中编译预处理的基本内容。结合C++中使用较多的地方,本章对宏及其相关应用做了详细讲解,依次介绍了宏的定义、调用、无参宏和带参宏的定义调用,以及宏与函数的区别等,对于难点部分,都安排了具体示例方便读者理解。此外,本章还对包含文件处理#include命令、条件编译相关命令等做了简要的介绍。学习完本章,读者应对编译器编译C++源程序的过程有一定理解,并了解如何优化程序的部分方法。小结
  • 13. 1.什么是预编译,何时需要预编译? 2.编写一个标准宏MIN,这个宏输入两个参数并返回较小的一个,注意参数在调用时可能是表达式的情况。 3.编写一个C++程序,在程序中定义一个不带参数的宏PI,使其完成求给定半径的圆的周长和面积。习题
  • 14. 习题4.下面程序段定义了两个宏,在主函数main()中使用了条件编译语句来控制程序的运行,读者仔细理解并写出输出结果。 #include #define CIR(r) r*r //带参数的宏定义 #define TEST //定义宏 void main() { int x=1; //定义并初始化变量 int y=2; int z; z=CIR(x+y); //调用宏 cout<<"CIR(x+y)= "<