C语言编译器在编译程序之前,会先使用预处理器(preprocessor)处理代码,代码经过预处理之后再送入编译器进行编译。
预处理器的主要任务包括宏定义、文件包含、条件编译等。
12.1 预处理指令
1、特点:
(1)预处理指令应该放在代码的开头部分。
(2)预处理指令都以 # 开头,指令前面可以有空白字符(比如空格或制表符),# 和指令的其余部分之间也可以有空格,但是为了兼容老的编译器,一般不留空格。#include <stdio.h>
(3)预处理指令都是一行,换行需要在行尾使用’\’
(4)预处理指令不需要分号作为结束符,指令结束是通过换行符来识别的。
(5)预处理指令通常不能写在函数内部,有些编译器的扩展允许将预处理指令写在函数里,但强烈不建议这么干。
12.2 宏定义
宏定义,就是用一个标识符(宏名称)来表示一个替换文本,如果在后面的代码中出现了宏名称,预处理器会将它替换为对应的文本,称为宏替换或宏展开。
#define 宏名称 替换文本宏名称:宏的名称,是一个标识符,通常使用大写字母表示,以便与变量名区分开来。替换文本:宏名称在代码中的每次出现都会被替换为这段文本。
取消宏定义
如要取消宏定义使用#undef命令
12.3 条件编译
1、#if
(1)#if...#endif
#if...#endif指令用于预处理器的条件判断,满足条件时,内部的行会被编译,否则就被编译器忽略。
#if 0
const double pi = 3.1415; // 不会执行
#endif
(2)#if...#else...#endif双向分支
(3)#if...#elif...#else...#endif多向分支
2、#ifdef
(1)#ifdef...#endif指令用于判断某个宏是否定义过,如果定义过就执行#ifdef...#endif中间的指令
有时源码文件可能会重复加载某个库,为了避免这种情况,可以在库文件里使用#define定义一个空的宏。通过这个宏,判断库文件是否被加载了。
(2)#ifdef...#else...#endif双向分支
(3)#ifdef...#elif...#else...#endif多向分支
3、#ifndef
(1)#ifndef...#endif跟#ifdef相反,用于判断某个宏没有定义过,如果没有定义过就执行#ifndef...#endif执行指定操作
#ifndef常用于防止重复加载。举例来说,为了防止头文件myheader.h被重复加载,可以把它放在#ifndef...#endif里面加载。
#ifndef MYHEADER_H
#define MYHEADER_H
#include "myheader.h"
#endif
上面示例中,宏MYHEADER_H对应文件名myheader.h的大写。只要#ifndef发现这个宏没有被定义过,就说明该头文件没有加载过,从而加载内部的代码,并会定义宏MYHEADER_H,防止被再次加载。
| 指令 | 说明 |
|---|---|
| #include | 包含一个源代码文件 |
| #define | 定义宏 |
| #undef | 取消已定义的宏 |
| #if | 如果给定条件为真,则编译下面代码 |
| #ifdef | 如果宏已经定义,则编译下面代码 |
| #ifndef | 如果宏没有定义,则编译下面代码 |
| #elif | 如果前面的#if给定条件不为真,当前条件为真,则编译下面代码 |
| #endif | 结束一个if……else条件编译块 |


被折叠的 条评论
为什么被折叠?



