Linux & 标准C语言学习 <DAY14>
一、预处理指令
程序员所编写的代码不能被真正的编译器所编译,需要先经过一段程序翻译一下
翻译的过程称为预处理,负责翻译的程序称为预处理器,被翻译的语句叫做预处理指令,以#开头的都是预处理指令
1、查看预处理的结果:
gcc -E code.c 把预处理的结果显示到终端
gcc -E code.c -o code.i 把预处理的结果存储到.i预处理文件
2、预处理指令的分类:
1.#include 头文件导入(拷贝)
#include <> 从系统指定路径查找头文件
#include "" 先从当前工作路径查找头文件,找不到再从系统指定文件中查找、
-I path 可以指定要查找的路径path
还可以通过设置变量环境来指定路径
2. #define 宏定义
宏常量:
#define MAX 50
优点:提高代码的可扩展性、可读性、安全性,还可以与case配合
注意:定义宏常量不要加分号,一般宏名全部大写
预定好的宏常量:
printf("%s\n",__func__); 获取函数名
printf("%s\n",__FILE__); 获取文件名
printf("%s\n",__LINE__); 获取行号
printf("%s\n",__DATE__); 获取日期
printf("%s\n",__TIME__); 获取时间
宏函数:
是带参数的宏 //不是真正意义上的函数,没有发生传参,也没有返回值
#define SUM(a,b) a+b
1.先把在代码中出现了宏函数的位置替换成宏函数后面的语句
2.再把代码中使用的参数替换成调用者的参数
注意:宏的内容必须保证在同一行,如果要换行,需要在每一行的末尾和下一行的开头添加续行符 \
宏函数的二义性:
由于宏函数代码位置、附近的值、参数等原因的影响,会导致宏函数有不同的解释
如何避免宏的二义性:
每个参数都加小括号保护,整体也加小括号保护,不要在宏函数的参数中使用自变运算符
#define SWAP(a,b) {typeof(a) t=a;a=b;b=t;} //宏定义交换任意两个变量的值 //typeof()定义一个用于接收返回值的变量
3.条件编译:根据条件决定让代码是否参与最终的编译
a.版本控制:
#if
#elif
#else
#endif
b.头文件卫士:防止头文件被重复包含,头文件必加
#ifndef HEAD_H //宏名不存在为真
#define HEAD_H
//
#endif
c.判断、调试
#ifdef DEBUG //宏名存在为真
#else
#endif
在编译时添加宏:gcc file.c -DDEBUG
*打印调试信息
#ifdef DEBUG
#define debug(...) printf(__VA_ARGS__) //转移参数
#else
#define debug(...)
#endif
*打印报错信息
#define error(...) printf("%s %s:%d %s %m %s",__FILE__,__func__,__LINE__,__VA_ARGS__,__DATE__,__TIME__)