1、文件包含
预处理指令#include用于包含头文件,有两种形式:#include <xxx.h>,#include “xxx.h”。
尖括号形式表示被包含的文件在系统目录中。如果被包含的文件不一定在系统目录中,应该用双引号形式。
在双引号形式中可以指出文件路径和文件名。如果在双引号中没有给出绝对路径,则默认为用户当前目录中的文件,此时系统首先在用户当前目录中寻找要包含的文件,若找不到再在系统目录中查找。
对于用户自己编写的头文件,宜用双引号形式。对于系统提供的头文件,既可以用尖括号形式,也可以用双引号形式,都能找到被包含的文件,但显然用尖括号形式更直截了当,效率更高。
./表示当前目录,…/表示当前目录的父目录。
2、宏定义(宏替换) #define
#define 用来进行宏定义。宏定义包括不带参数宏定义和带参数宏定义两种。
(1)不带参数的宏定义
形式:#define 标志符 字符串
例如:#define PI 3.1415926
作用:用一个标识符去代替一个字符串。在编译时,将宏名替换成字符串的过程称为“宏展开”。
优点:使用宏定义可以减少程序中重复书写某些字符串的工作量,也可以减少出错率。
作用域:宏定义的有效范围称为宏名的作用域,宏名的作用域从宏定义的结束处开始到其所在的源代码文件末尾。如果需要终止宏名的作用域,可以用预处理指令#undef加上宏名。
注意:宏定义只做字符替换,不分配内存空间。宏替换不占运行时间,只占用编译时间。
(2)带参数的宏定义
形式:#define 宏名(参数表) 字符串
例如:#define S(a,b) ab
area=S(2,3);
展开过程:按#define命令中指定的字符串从左到右进行替换。
注意:带参数的宏定义类似于函数,在调用时,形参与实参一一对应,与函数调用的方法相似。但二者有本质区别:函数调用时,要先求出实参表达式的值,然后带入形参;而宏定义只是单纯的进行字符串替换,不涉及运算。
在c语言中,#define用来建立常量,或者定义带参数的宏。而在c++中仍然保留了这些特征,但是经常用const语句代替不带参数的宏,用inline内联函数代替带参数的宏。
3、条件编译指令
一般情况下,在进行编译时对源程序中的每一行都要编译,但是有时希望程序中某一部分内容只在满足一定条件时才进行编译,如果不满足这个条件,就不编译这部分内容,这就是条件编译。条件编译主要是进行编译时进行有选择的挑选,注释掉一些指定的代码,以达到多个版本控制、防止对文件重复包含的功能。#if,#ifndef,#ifdef,#else,#elif,#endif是比较常见条件编译预处理指令,可根据表达式的值或某个特定宏是否被定义来确定编译条件。
① 指令意义
#if 表达式非零就对代码进行编译;
#ifdef 如果宏被定义就进行编译;
#ifndef 如果宏未被定义就进行编译;
#else 作为其它预处理的剩余选项进行编译;
#elif 这是一种#else和#if的组合选项;
#endif 结束编译块的控制。
② 常用形式
#if_#endif形式:
#if 常数表达式 或 #ifdef 宏名 或 #ifndef 宏名
程序段
#endif
如果常数表达式为真或者该宏名已定义或者该宏名未定义,则编译后面的程序段;否则就不编译,跳过这段程序。
#if_#else_#endif形式:
#if 常量表达式 或 #ifdef 宏名 或 #ifndef 宏名
程序段1
#else
程序段2
#endif
如果常数表达式为真或者该宏名已定义或者该宏名未定义,则编译后面的程序段1;否则编译后面的程序段2。
#if_#elif_#endif形式:
#if 常量表达式1
程序段1
#elif 常量表达式2
程序段2
…
#elif 常量表达式n
程序段n
#endif
注意这种形式#elif不可以用于#ifdef和#ifndef中,但#else可以。
③ 表达式
预处理器表达式包括的操作符主要涉及到单个数的操作(+、-、~、<<、>>)、多个数的运算(、/、%、+、-、&、^、|)、关系比较(<、<=、>、>=、==、!=)、宏定义判断(defined)、逻辑操作(!、&&、||),其优先级和行为方式与C++表达式操作符相同。对于预处理器表达式,一定要记住它们是在编译器预处理器上执行的,是在编译前进行的。
例子:#ifndef 与#if !defined意义相同,#ifdef 与#if defined意义相同。
C++中预处理器的学习
最新推荐文章于 2023-03-09 09:41:23 发布