预处理指令
include
include 会将头文件的内容导入程序中
include “” 在用户当前目录文件下查找,如果没有再去系统默认路径
include<> 直接去系统默认路径下查找
导入头文件是 会优先考虑xxx.h.gch 这时即使修改.h文件亦不会有作用
define
定义宏常量
#define PI 3.14
#define N 10
宏就是简单的替换所以如果遇到运算需要将内容用括号括起来,以免造成歧义
typedef 和 宏常量的区别
typedef int * A
#define B int *
A s1,s2; s1 s2 都是 int *类型
B s3,s4; 只有s1是int* s2是int
宏定义既可以在全局区也可以在函数内部
宏定义不一定非要定义的内容
编译时 可以通过 gcc -D a=11 xx.c 这种形式定义宏
#undef 宏 删除定义的宏
宏名称为一个标识符,可以替换标识符,也可以替换值和内容
#define A a
int a = 10;
printf("%d\n",A); //10
宏可以折行 一定宏可以定义在多行,宏定义如果要折行,需要在行尾使用 \
注意:宏常量 和const 常量的区别
宏常量是真的常量 而const 并不是 例如定义可边长数组时只能用前者
从内存上看:宏常量不需要分配内存 const常量需要
从使用上看:宏常量在预处理阶段就全部替换 const则需要在使用时从内存中加载
C语言标准预定义的宏
__FILE__ :当前文件名
__FUNCTION__ :当前函数名
__func__ :当前函数名
__LINE__ :当前行号 可以使用 #line no 来指定下一行开始的行号
__DATE__ :编译代码的日期 年月日
__TIME__ :编译代码的时间 时分秒
__STDC__ :编译器是否使用C标准 1:是的 0:不是
日志 输出内容时(显示输出的这个内容的代码是在哪个文件,哪个函数,哪一行输出)
定义宏函数
带参数的宏,在使用宏时可以传递参数
#define MACRO_NAME(arglist) CONTENT
宏函数在预处理阶段就会被替换 不存在调用函数一说
宏函数的参数不需要类型 只需要标识符
宏参数在使用参数时,需要对每个参数都加()
#define SQR1(x) x*x
#define SQR2(x) (x)*(x)
#define SQR3(x) ((x)*(x))
int a = SQR1(3+5); // 3+5*3+5
int b = SQR2(3+5); // (3+5)*(3+5)
int c = 64/SQR2(3+5); // 64/(3+5)*(3+5)
int d = 64/SQR3(3+5); // 64/((3+5)*(3+5))
宏函数的参数可以是类型
宏函数的参数也可以是可变长的
__VA_ARGS__
#define MACRO_FUNC(...) CONTENT //宏函数,可以没有有名参数
void func(int argname,...){
//普通函数,至少有一个有名参数
}
#define LOG(format,...) \
printf("%s %s %d:"format,__FILE__,__func__,__LINE__,##__VA_ARGS__)
#define log(format,args...) \
printf("%s