初学C语言day09--宏定义
预处理指令
程序员所编写的代码并不是能被编译器直接编译的标准C代码,需要一段程序翻译一下
翻译的程序称为预处理器,翻译的过程叫做预处理,需要被翻译的代码叫做预处理指令,以#开头的都是预处理指令
查看预处理结果:
gcc -E code.c 把预处理的结果显示到终端
gcc -E code.c -o code.i 把预处理的结果存储到.i文件
预处理指令的分类:
#include 导入头文件
#include <> 从系统指定路径查找头文件
#include "" 先从工作路径查找头文件,如果找不到再从系统指定路径查找
gcc code.c -I /path 先从path查找,找不到再根据<>""
通过修改操作系统的环境变量来指定头文件的查找路径
#define 定义宏
宏常量
#define MAX 50
优点:提高了代码的可扩展性、提高可读性、提高安全性、与case配合
注意:一般宏名全部大写,末尾不要加分号
函数名全部小写+下划线 全局变量首字母大写 局部变量全部小写 指针+p 数组arr 字符串str
预定义好的宏常量:
printf("%s\n",func); 获取函数名
printf("%s\n",FILE); 获取文件名
printf("%d\n",LINE); 获取行号
printf("%s\n",DATE); 获取日期
printf("%s\n",TIME); 获取时间
宏函数
其实就是带参数的宏替换
不是真正的函数
不检查参数类型、没有传参、没有返回值、只有计算结果
#define SUM(a,b) a+b
1、先把代码中出现了宏函数的位置替换成 宏后面的式子
2、再把式子中的参数替换成调用者提供的参数
注意:宏函数可以用大括号进行保护,宏不能直接换行,需要在末尾添加续行符 \
宏函数的二义性:
由于宏所处的位置、周围的数据和参数不同,导致同一个宏可能有不同的解释,这种叫做宏的二义性
如何避免宏的二义性:
1、宏函数整体加小括号,每个参数都加小括号
2、使用宏函数时不要提供带自变运算符的参数
注意:容易出选择题,考分辨二义性
宏函数与普通函数的区别?
宏函数:只是带参数的宏替换,不是真正的函数,没有独立的栈内存,只是用法像函数
函数:是一段具有某项功能的代码集合,会被编译成二进制指令存储在代码段,有独立的命名空间、栈内存
有什么不同?
宏函数:结果 不检查 危险 替换 速度快 冗余
函数:返回值 类型检查 安全 跳转 速度慢 就一份
#define 与 typedef 的区别
typedef int num;
#define num int
num n;
#define是宏替换 typedef是类型重定义
如果是普通类型时,它们用法上没有任何区别
typedef int* INTP;
INTP p1,p2,p3; // 都是指针
#define INTP int*
int* p1,p2,p3; // p1是指针 p2p3是int
条件编译
根据条件决定让哪些代码参与编译
版本控制:
#if
#elif
#else
#endif
头文件卫士:
防止头文件被重复包含
#ifndef 宏名 //如果宏不存在条件为真
#define 宏名
...
#endif//宏名
注意:宏名用头文件名全部大写,.用下划线代替
判断、调试代码:
#ifdef 宏名 //如果宏存在条件为真
#else
#endif
gcc code.c -D宏名 编译时定义宏
// 打印提示信息
#ifdef DEBUG
#define debug(...) printf(__VA_ARGS__)
#else
#define debug(...)
#endif
// 打印错误信息
#define error(...) printf("%s %s:%d [%s] %m %s %s\n",__FILE__,__func__,__LINE__,__VA_ARGS__,__DATE__,__TIME__)
头文件
头文件中应该写什么?
背景:头文件可能被任意的源文件包含,意味着头文件的内容会在多个目标文件中存在,因此需要确保链接合并时不能冲突
重点:头文件中只能编写声明语句,不能有定义语句
全局变量的声明
函数声明
宏常量
宏函数
typedef 类型重定义
结构、联合、枚举类型设计
头文件的编写原则:
1、为每个.c文件写一份.h文件,.h文件是对它.c文件的说明
2、如果需要使用某个.c文件中的变量、函数、宏、结构等,只需要把该.c文件的.h文件导入即可
3、.c文件也要导入自己的.h文件,目的是让声明与定义一致
头文件的相互包含:
假设a.h中包含了b.h,而b.h又包含了a.h,这种情况叫做头文件相互包含,会导致出现 未知类型名 "xxx" 报错
解决方法:把a.h和b.h中相互需要的内容提取出来写一个c.h,然后让a.h b.h调用c.h
Makefile
Makefile是由一些列的编译指令组成的编译脚本文件,也是可执行文件
一个基本的Makefile的格式:
执行目标: 依赖
编译命令
被依赖的目标1:依赖
编译命令
被依赖的目标2:依赖
编译命令
...
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)