预处理命令字:用于表示一个预处理命令
1.头文件的引用:include
2.宏定义: define
文件的包含方式
1.#include “filename”
2.#include < filename >
这两种引用方式之间的区别就在于,在以< filename> 方式引用的时候,如果在windos环境下采用IDE(如:codebloks)进行编译,那么会先在系统头文件目录中查找,若查找失败,再到当前目录中查找,还查找不到则报错;如果在Linux 环境下采用 gcc 进行编译,那么仅在系统头文件目录中查找,查找不到则报错。
宏定义
优点
- 提升代码的可移植性
#define INT_SIZE sizeof(int)
// 因为sizeof(int) 在不同的编译环境下的运行结果有可能不同
// 所以此种情况下最好使用宏定义
- 减少不必要的修改,提升程序的可预读性
#define PI 3.1415926
// 如果需要修改pi的值仅需要在此处修改即可
注意事项
- 宏替换不做语法检查,所以在使用的时候要格外小心,必要的时候可以用const 替代 define
- 不要在字符串中使用宏,如果宏名出现在字符串中,那么将按字符串进行处理
- 宏替换通常在文件开头部分,写在函数的花括号外边,作用域为其后的程序,直到用 #undef 命令终止宏定义的作用域
#include <stdio.h>
#include <stdlib.h>
#define PI 3.1415926
int main()
{
printf("%f\n" , PI );
#undef PI
int PI = 2 ;
printf("%d\n" , PI );
return 0;
}
普通宏定义
1.语法:#define 标识符 字符串
带参数的宏定义
1.语法: #define 宏名(参数表) 表达式
2.注意事项
(1) 宏名和参数表的括号间不能有空格。
(2) 宏替换只做替换,不做计算和表达式求解,这一点要格外注意。
#define A 10+20
#define B 50+30
// A * B = 10 + 20 * 50 + 30
#define C (10+20)
#define D (50+30)
// C * D = (10 + 20) * (50 + 30)
(3) 宏替换在编译前进行,不分配内存。
(4) 宏替换不存在类型,也没有类型转换
(5) 宏在预处理阶段就会被替换
嵌套宏替换
1.在一个宏定义中嵌套其他的宏
2.示例
#define N 55
#define area N*N
条件编译指令
1.预处理程序提供了条件编译的功能,用户可以选择性地编译程序,进而产生不同的目标代码文件
2.定义方式
#if 常量表达式
代码1
#else
代码2
#endif
//当常量表达式为真,执行代码1,否则执行代码2
#ifdef 标识符
代码1
#else
代码2
#endif
// 如果标识符被#define定义,则执行代码1,否则执行代码2
#ifndef 标识符
代码1
#else
代码2
#endif
// 如果标识符未被#define定义,则执行代码1,否则执行代码2
// 还可以注释代码段
#if (0)
注释代码段;
#endif
- 应该要注意的问题:常量表达式不能是变量和含有sizeof 等在编译时求值的操作符,在使用条件编译命令时尤其要注意。