C预处理器
C预处理器
C预处理器处理程序的源代码,在编译之前运行,通常以符号#
开头,C语言的预处理主要有3个方面的内容(下三)
1. 宏定义和宏替换 #define
"宏"是借用汇编语言中的概念,为了是方便作一些定义和扩展
以#define
开头,分为
- (1) 符号常量的宏定义
- (2) 带参数的宏定义
1.1 符号常量的宏定义:#define 标识符 字符串
注:其中标识符就是宏名称,用来标识常量字符串的,另外宏定义末尾不加分号
由于预处理是在编译之前,故预处理不做语法检查
且宏定义不分配内存,变量定义才会分配内存
1.2 带参数的宏定义及其替换 : #define 标识符(参数表) 字符串
对带参数的宏定义进行宏替换时,不仅对宏标识符作字符串替换,还必须做参数的替换
例: 有宏定义 #define Func(x) (x*x)
,则 Fun(a+B)
将会被替换成什么?
答: 替换成 (a+B*a+B)
可见如果想实现(a+B)*(a+B)
,则正确的宏定义应该为:#define Func(r) ((r)*(r))
故:为了避免宏替换时发生错误,宏定义中的宏参数应加上括号
宏定义可以嵌套使用:
例:
#define ADD(x, y) x+y
int m = 3;
m + = m * ADD(m, m);
则 m = ?
解析:
m + = m* ADD(m, m);
m = m + m * m + m = 3+ 3*3 +3 = 15
1.3 宏定义的本质即文本替换:
关于宏定义和宏替换注意点
- 宏名一名大写(标识符);宏名与参数括号之间不能有空格,末尾无分号
- 宏替换只做替换,不检查语法,不做计算,不做表达式求解
- 宏替换在编译前进行,不分配内存,函数调用在编译后程序运行时进行,并分配内存
- 函数只有一个返回值,利用宏则可设法有多个值
- 宏替换使源程序变长,函数调用不会
- 宏替换不占运行时间,只占编译时间,函数调用占运行时间
注: 应尽量少用宏替换,在C++中,宏替换实现的常量功能由const,enum
代替,带参数的宏替换由模板内联函数代替
2. 文件包含 #include
#include <iostream>
:< >标准头文件
#include "a.h"
: " "自定义头文件
3. 条件编译
作用:可使同一源程序根据不同编译条件(参数)产生不同的目标代码,便于调试和移植
形式:(条件编译控制语句有不同形式)
#if / ifdef / ifndef
#elif
#else
#endif
文件包含需避免多重
包含,下面介绍利用条件编译语句避免多重包含:
- 1、为避免名字冲突,预处理器变量经常用大写字母表示
- 2、预处理器变量有两种状态:已定义和未定义
#define
指示一个名字并定义该名字为预处理器变量
#ifndef
检测指定的预处理变量是否未定义,如果预处理器变量未定义,那么跟在其后的所有语句都被处理,直到出现#endif
举个格式例子
#ifndef SALESITEM_H
#define SALESITEM_H
// 此处是某个类的定义与相关函数定义
#endif
为了保证头文件在给定的源文件中只处理一次,首先检测#ifndef
,若第一次处理,则#ifndef
后面的语句执行,直到#endif
,那样,已定义过后,之后编译时就会忽略。