嵌入式Linux C(十)——编译预处理
文章目录
一、宏定义指令
1.0前言
宏一定要大写
预处理:
- 预处理主要任务:1.头文件展开 2. 宏替换 3. 条件编译 gcc -E
- 头文件展开:#include <> VS #include “”
<>:包含系统定义的头文件(/usr/include),搜索路径:/usr/onclude 系统的头文件目录
“”:包含自定义的头文件,搜索路径:现在当前目录查找,再到系统头文件目录查找
gcc -l 指定头文件第三方
1.1 定义常量与命令
- 宏替换
- 宏语法:#define NAME Value
- 替换逻辑:傻瓜式替换 注意事项:使用()解决运算符优先级问题
- 作用:定义常量(杜绝幻数) 提高代码可读性
1.2 定义宏函数
普通自定义函数
开销大,:给形参分配空间
一系列操作:函数调用、函数返回、分配空间、释放空间(运行时间)
宏定义函数:频繁调用,且短小的函数,最好优化成宏函数(不安全)(do while(0)的作用)
傻瓜式替换,不占用空间,在预处理阶段编译(编译时间)
定义函数(宏函数):用编译时间换内存空间(用空间换运行时间:inline:修饰函数(不超过5行、不能要全局变量、静态变量、) 内嵌函数)
宏函数 VS 自定义函数
常用宏函数:(看课本)
1.3 内置宏定义
1.3.1 (#)
功能:是将其后面的宏参数进行字符串化操作
#include <stdio.h>
#define WARN_IF(EXP) \
do \
{ \
if(EXP) \
printf("%s\n",#EXP); \
}while(0)
int main()
{
int num = 5;
WARN_IF(num == 5);
return 0;
}
1.3.2 (##)
用于做连接
#define LINK_MULTPLE(a,b,c,d) a##_##b##_##c##_##d
typedef struct _record_type LINK_MULTPLE(name,company,position,salary)
typedef struct _record_type name_company_position_salary
1.3.2 内置宏
printf("%d\n",__ LINE );打印行号(调试,找错误,段错误)
printf("%s:%d\n", func__,__ LINE__);加上所在函数
printf("%s",__ DATE__);显示日期
printf("%s",__ TIME__);显示时间
1.4 扩展
1.4.1 typedef与#define的区别
1.4.2 枚举与#define的区别
#undef 取消已定义的宏
二、条件编译指令
#if 如果给定条件为真,则编译下面代码
#ifdef 如果宏已经定义,则编译下面代码
#ifndef 如果宏没有定义,则编译下面代码
#elif 如果前面的#if给定条件不为真,当前条件为真,则编译下面代码,其实就是else if的简写
#else 跟else效果一样
#endif 结束一个#if……#else条件编译块
#error 停止编译并显示错误信息
#include <stdio.h>
int main()
{
//条件编译:按照给定的条件编译代码(只影响编译不影响运行)
printf("hello world\n");
printf("welcome to jsetc");
return 0;
}
gcc demo7.c -DMAX_SIZE=1024 -o demo7
-D:向云文件定义一个宏 -D宏的名字
应用场景:
- 注释代码
- debug_msg
- 防止头文件重复包含导致的重复定义的问题
#include <stdio.h>
#ifndef __DEBUG__
#define debug_msg(fmt,args...)
#else
#define debug_msg(fmt,args...) printf(fmt,##args)
#endif
int main()
{
debug_msg("%s:%d\n",__TIME__,__LINE__);
printf("hello world\n");
printf("welcome to jsetc\n");
return 0;
}
gcc if#.c -D__DEBUG__ -o if# 开启调试
gcc if#.c -o if# 没有开启
//func1.h
#ifndef __FUNC2_H__
#define __FUNC2_H__
int a = 5;
#endif
//最新
#pragma once
int a = 5;
可以避免头文件重复包含导致的重复定义的问题
三、其他预处理指令
#include
#define
#undef 取消已定义的宏
#if 如果给定条件为真,则编译下面代码
#ifdef 如果宏已经定义,则编译下面代码
#ifndef 如果宏没有定义,则编译下面代码
#elif 如果前面的#if给定条件不为真,当前条件为真,则编译下面代码,其实就是else if的简写
#else 跟else效果一样
#endif 结束一个#if……#else条件编译块
#error 停止编译并显示错误信息
四、debug_msg的使用
#include <stdio.h>
#ifndef __DEBUG__
#define debug_msg(fmt,args...)
#else
#define debug_msg(fmt,args...) printf(fmt,##args)
#endif
int main()
{
debug_msg("%s:%d\n",__TIME__,__LINE__);
printf("hello world\n");
printf("welcome to jsetc\n");
return 0;
}
gcc if#.c -D__DEBUG__ -o if# 开启调试
gcc if#.c -o if# 没有开启
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理