#ifndef FLOW_EXT #define FLOW_EXT extern

.c 文件里面:#define FLOW_EXT, .h文件里面:#ifndef FLOW_EXT #define FLOW_EXT extern #endif FLOW_EXT u16 t_boundary_1s; 怎么理解?

1. 在 .c 文件中

c

复制代码
// source.c
#define FLOW_EXT          // 定义 FLOW_EXT 宏(值为空)
#include "header.h"

// 此时头文件中的代码会这样展开...

2. 在 .h 文件中

h

复制代码
// header.h
#ifndef FLOW_EXT                        // 检查 FLOW_EXT 是否未定义
#define FLOW_EXT  extern                // 如果未定义,定义为 "extern"
#endif

FLOW_EXT u16 t_boundary_1s;            // 使用 FLOW_EXT 修饰变量

关键:展开结果不同

情况1:在定义了 FLOW_EXT 的 .c 文件中

c

复制代码
// FLOW_EXT 已定义(值为空),所以跳过 #define
// 直接执行:FLOW_EXT u16 t_boundary_1s;
// 展开为:(空) u16 t_boundary_1s;
// 最终:u16 t_boundary_1s;  ← 这是变量定义(分配内存)

情况2:在未定义 FLOW_EXT 的其他 .c 文件中

c

复制代码
// FLOW_EXT 未定义,执行 #define FLOW_EXT extern
// 然后:FLOW_EXT u16 t_boundary_1s;
// 展开为:extern u16 t_boundary_1s;  ← 这是变量声明(不分配内存)

完整示例

global.h

h

复制代码
#ifndef GLOBAL_H
#define GLOBAL_H

typedef unsigned short u16;

#ifndef FLOW_EXT
#define FLOW_EXT extern
#endif

FLOW_EXT u16 t_boundary_1s;    // 魔法在这里!

#endif

main.c(定义变量的文件)

c

复制代码
#define FLOW_EXT           // 关键:先定义这个宏
#include "global.h"

// 经过预处理后,上面那行变成:
// u16 t_boundary_1s;     ← 实际定义变量,分配内存

void main() {
    t_boundary_1s = 100;   // 可以直接使用
}

other.c(使用变量的文件)

c

复制代码
// 不定义 FLOW_EXT
#include "global.h"

// 经过预处理后,上面那行变成:
// extern u16 t_boundary_1s;  ← 只是声明,不分配内存

void func() {
    t_boundary_1s = 200;   // 引用 main.c 中定义的变量
}

核心理解

文件 FLOW_EXT 状态 宏展开 实际代码 作用
main.c #define FLOW_EXT u16 t_boundary_1s; 定义(分配内存)
other.c 未定义 extern extern u16 t_boundary_1s; 声明(引用外部)

为什么这样设计?

传统方式需要维护两处:

h

复制代码
// 需要在头文件和源文件分别声明
extern u16 t_boundary_1s;  // .h文件
u16 t_boundary_1s;          // 某个.c文件

这种技巧的优势

  • 单一维护点:只需在头文件中写一次变量声明

  • 自动区分 :通过 #define FLOW_EXT 控制是定义还是声明

  • 防止重复定义:只有一个文件会实际定义变量

  • 代码清晰:明确哪个文件是变量的"所有者"

这是一种优雅的全局变量管理技巧,在嵌入式系统和大型C项目中很常见!

相关推荐
明月清了个风1 天前
libmodbus笔记
笔记·嵌入式软件·libmodbus
波特率1152003 天前
单片机启动流程以STM32举例
stm32·单片机·嵌入式硬件·嵌入式·嵌入式软件
戏舟的嵌入式开源笔记12 天前
上手RP2040(基于C SDK)
c语言·pico·嵌入式软件·rp2040
戏舟的嵌入式开源笔记12 天前
RP2040(移植FreeRTOS-SMP)
rtos·嵌入式软件
笨笨饿16 天前
42_C语言查找算法
linux·服务器·c语言·人工智能·mcu·学习方法·嵌入式软件
Lester_110119 天前
全局变量与函数内的静态局部变量名字相同
嵌入式软件
小向是个Der20 天前
嵌入式进阶——嵌入式MCU编译工具链总结
单片机·编译·嵌入式软件·cline+glm5.0
AF_INET61 个月前
RV1126B开发板学习篇(二)v4l2+mpp编码
c语言·经验分享·音视频·视频编解码·嵌入式软件·rv1126b
逆小舟1 个月前
【SWM320】学习使用UART
单片机·学习·嵌入式软件