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 testprintf("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==USAchar *currency="dollar"; //有效#elif ACTIVE_COUNTRY==ENGLANDchar *currency="pound";#elsechar *currency="france";#endifvoid 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) //如果定义了宏Nint a=666;#endifvoid main() {printf("%d",a);}
输出: 666
10.4.2 #ifdef … #endif
#define INTEGER 122#ifdef INTEGERint add(int x, int y) { //有效return x+y;}#elsefloat add(float x, float y) {return x+y;}#endifvoid main(){#ifdef INTEGERint a,b,c; //有效scanf("%d%d",a,b);printf("%d",add(a.b));#elsefloat a,b,c;scanf("%f%f",a,b);printf("%f",add(a.b));#endif}
