10.1 预处理命令简介
C语言源程序中以 **#**
开头、以换行符结尾的行成为预处理命令。包括:
- 宏定义
#define
#undef
- 文件包括
#include
- 条件编译
#if
#ifdef
#else
#elif
#endif
- 其他
#line
#error
#pragma
10.2 宏定义
10.2.1 不带参的宏定义
#define 标识符 单词串
- 通常用大写字母定义宏名。
宏定义时,如果单词串太长,可以在行尾使用反斜线
\
续航符。#define LONG_STRING "this is a very long string that is\
used as an example"
如果要终止宏的作用域,可以使用
#undef 标识符
命令#define N 100 //宏定义
int sum() {
...
}
#undef N //宏取消,下方代码宏不再生效
void main(){
...
}
宏可以嵌套定义,不能递归定义 ```c
define R 2.0
define PI 3.14159
define L 2PIR //正确
define M M+10 //错误,不可递归定义宏
5. 程序中字符串常量不作为宏进行宏替换操作
```c
#define XXX this is a test
printf("XXX"); //输出XXX,而不是this is a test
- 宏定义一般以换行结束。不是说不能用分号结尾,而是分号会作为单词串中的一个字符一起进行宏替换,容易引起一行语句两个分号的不必要的错误。
- 宏可以被重复定义。
- 宏如果是一个表达式,一定要将这个表达式括起来,否则可能会产生错误。
```c
define NUM1 10
define NUM2 20
define NUM NUM1+NUM2
void main() {
int a=2, b=2;
a=NUM; //宏替换后为 a=10+20
b=bNUM; //宏替换后为 b=b10+20
printf(“%d %d”,a,b);
}
输出结果为: `60 40` ,而不是 `40 40`
<a name="Mf6rf"></a>
### 10.2.2 带参数的宏定义
这样的宏因为定义成一个函数调用的形式,因此也被称为类函数宏。<br />`#define 标识符(参数列表) 单词串`
- 参数列表中的参数只有参数名,**没有数据类型**,之间用逗号隔开
- 单词串是宏的内容文本,也称为**宏体**,其中通常会引用宏的参数
```c
#define MAX(x,y) ( ( (x) > (y) ) ? (x) : (y) )
void main(){
int a=2,b=3;
a=MAX(a,b)+3; //宏替换为 a=(( (a) > (b) ) ? (a) : (b) )+3
}
define N 3
define Y(n) ((N+1)*n)
void main() {
int z=2(N+Y((5+1)));
//如果5+1不打括号,结果为48!因为Y(5+1)被替换为((3+1)5+1),而Y((5+1))才是Y(6)
printf(“%d”, z);
}
输出结果
54
**宏的本质是不考虑逻辑的替换!!!**
2. **定义带参数的宏时,宏名与参数列表的括号之间不能有空格,否则会变成定义一个不带参数的宏!!!**
<br />
<a name="gBKzA"></a>
## 10.3 文件包含
文件包含是指,一个C语言源程序通过 `#include` 命令将另一个文件(通常是.c、.cpp或.h文件)的全部内容包含进来。<br />`#include <包含文件名> 或 #include "包含文件名"`
- 使用<>:直接到系统指定的“文件包含目录”去查找被包含的文件。
- 使用"":系统先到当前目录下查找被包含文件,如果没找到,再到直接到系统指定的“文件包含目录”去查。一般地说,使用双引号比较保险。双引号之间还可以指定包含文件的路径,如 `#include "c:\\prg\\p1.h"` 。注意转义字符 `\\` 。
- 一条包含命令只能指定一个被包含文件。
- 包含文件可以嵌套,即被包含文件中又包含另一个文件。
<a name="eBZfH"></a>
## 10.4 条件编译
<a name="bxZ9k"></a>
### 10.4.1 #if … #endif
```c
#define USA 0
#define ENGLAND 1
#define FRANCE 2
#define ACTIVE_COUNTRY USA
#if ACTIVE_COUNTRY==USA
char *currency="dollar"; //有效
#elif ACTIVE_COUNTRY==ENGLAND
char *currency="pound";
#else
char *currency="france";
#endif
void main(){
float price1, price2, sumprice;
scanf("%f%f", &price1, &price2);
sumprice=price1+price2;
printf("sum=%.2f%s", sumprice, currency);
}
#if和#elif常与defiend命令配合使用**defined(宏名) 或 defined 宏名**
#include<stdio.h>
#define N 30
#if defined (N) //如果定义了宏N
int a=666;
#endif
void main() {
printf("%d",a);
}
输出: 666
10.4.2 #ifdef … #endif
#define INTEGER 122
#ifdef INTEGER
int add(int x, int y) { //有效
return x+y;
}
#else
float add(float x, float y) {
return x+y;
}
#endif
void main(){
#ifdef INTEGER
int a,b,c; //有效
scanf("%d%d",a,b);
printf("%d",add(a.b));
#else
float a,b,c;
scanf("%f%f",a,b);
printf("%f",add(a.b));
#endif
}