#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项目中很常见!

相关推荐
AF_INET65 天前
RV1126B开发板学习篇(二)v4l2+mpp编码
c语言·经验分享·音视频·视频编解码·嵌入式软件·rv1126b
逆小舟16 天前
【SWM320】学习使用UART
单片机·学习·嵌入式软件
香水5只用六神21 天前
【RTOS快速入门】05_动态_静态创建任务(2)
c语言·stm32·单片机·嵌入式硬件·freertos·rtos·嵌入式软件
香水5只用六神21 天前
【RTOS快速入门】06_任务状态理论讲解(1)
c语言·stm32·单片机·嵌入式硬件·freertos·rtos·嵌入式软件
香水5只用六神22 天前
【RTOS快速入门】07_同步互斥与通信概述
单片机·嵌入式硬件·学习·操作系统·freertos·rtos·嵌入式软件
香水5只用六神22 天前
【RTOS快速入门】05_动态_静态创建任务(1)
c语言·开发语言·单片机·嵌入式硬件·freertos·rtos·嵌入式软件
hateregiste1 个月前
嵌入式软件开发中常见知识点问答集锦!
c语言·单片机·嵌入式软件
Lester_11011 个月前
STM32 电机控制应用中,ICxFilter,ICxPSC以及高级定时器的采样时钟分频CKD区别是什么
单片机·嵌入式硬件·嵌入式软件·电机控制
螺丝钉的扭矩一瞬间产生高能蛋白1 个月前
深入剖析FreeRTOS优先级继承机制:vTaskPriorityInherit与xTaskPriorityDisinherit源码解析
stm32·freertos·嵌入式软件·优先级反转