define保护 #i fndef HEAdERName H #def ine headername h vecmat, h #ifndef vEc Mat h #define VEc mat H 头文件内容 typedef struct I #end if float x, y vec; 注意宏定义 HEADERNAME H typedef struct I float m[3][3] 在模块中 mat 必须是唯一的 不要重复 #end if// ifndef VEC MAT H
#ifndef _HEADERNAME_H #define _HEADERNAME_H <头文件内容> #endif 注意宏定义_HEADERNAME_H 在模块中 必须是唯一的 不要重复 vecmat.h #ifndef _VEC_MAT_H #define _VEC_MAT_H typedef struct { float x, y, z; } vec; typedef struct { float m[3][3]; } mat; #endif // ifndef _VEC_MAT_H 11
编译预处理 ◇编译器对源代码开始编译之前,首先对.c文件进行预处 理 ◎读取c源程序,对其中的预处理指令(以排开头的指令)和特 殊符号进行处理 或者说,扫描源代码,对其进行初步的转换,生成新的源代 码提供给编译器。 ◇预处理指令 @以#号开头的代码行 ◎#号必须是该行除了空白字符外的第一个字符。 #号后是指令关键字 在关键字和#号之间允许存在任意个数的空白字符。 整行语句构成了一条预处理指令 ◇编译器通过预处理指令,对源代码做相应转换
编译器对源代码开始编译之前,首先对.c文件进行预处 理 读取c源程序,对其中的预处理指令(以#开头的指令)和特 殊符号进行处理。 或者说,扫描源代码,对其进行初步的转换,生成新的源代 码提供给编译器。 预处理指令 以#号开头的代码行 #号必须是该行除了空白字符外的第一个字符。 #号后是指令关键字 在关键字和#号之间允许存在任意个数的空白字符。 整行语句构成了一条预处理指令 编译器通过预处理指令,对源代码做相应转换。 12
常用的预处理指令 ◆# inc lude文件包含指令 #inc lude <stdio. h> ◇# def ine宏定义指令 #def ine LIB version 2 ◇# undef宏定义取消指令 #undef inux ◇条件编译指令 #i fdef/#ifndef #ifndef M Pl <条件对应的代码> #define Mpi 3. 1415926 end if #end if ◇条件编译指令 #讦表达式 #if llb vers ion ==2 <表达式非零时编译的代码〉 适合版本2的代码> # e se #else <否则编译的代码〉 terror"Only support V2 #el if #end if # error停止编译预处理并输岀错误信
#include 文件包含指令 #define 宏定义指令 #undef 宏定义取消指令 条件编译指令 #ifdef/#ifndef <条件对应的代码> #endif 条件编译指令 #if表达式 <表达式非零时编译的代码> #else <否则编译的代码> #elif #error 停止编译预处理并输出错误信息 #include <stdio.h> #define _LIB_VERSION 2 #undef _linux #ifndef M_PI #define M_PI 3.1415926 #endif #if _LIB_VERSION ==2 <适合版本2的代码> #else <适合其他版本的代码> #endif 13 #error "Only support V 2
define保护 #ifndef vEc mat h #define VEC mat H typedef struct i 通过# define保护,当头文件被 float x, y 重复 include的时候, vec 内容不会被重复 include typedef struct <在同一个程序模块中不重复> float m[3][3] mat #endif// ifndef VEC MAT H
#ifndef _VEC_MAT_H #define _VEC_MAT_H typedef struct { float x, y, z; } vec; typedef struct { float m[3][3]; } mat; #endif // ifndef _VEC_MAT_H 14 通过#define保护,当头文件被 重复include的时候, 内容不会被重复include <在同一个程序模块中不重复>
define保护 ◇保证了在编译一个c文件时,头文件的不被 重复编译 ◇在编译其他.c文件时,该头文件任然会被编译 ◇记住:编译c文件是独立进行的 因此,一般地,头文件中不能出现函数定义和 变量的定义。 ◆否则如果有多个c文件包含它时,仍然会编译 生成重复的变量和函数定义。 ◇重复的变量或函数定义会导致Link错误
保证了在编译一个c文件时,头文件的不被 重复编译 在编译其他.c文件时,该头文件任然会被编译 记住:编译c文件是独立进行的 因此,一般地,头文件中不能出现函数定义和 变量的定义。 否则如果有多个c文件包含它时,仍然会编译 生成重复的变量和函数定义。 重复的变量或函数定义会导致Link错误! 15