C 语言 static 完整讲解

📅 2026/6/27 6:39:32
C 语言 static 完整讲解
C 语言 static 完整讲解分三大场景static是存储修饰符作用分全局变量、局部变量、函数三种场景核心两个能力改变内存存放区域限制作用域文件隔离。一、场景 1修饰局部变量函数内部1. 普通局部变量无 staticc运行void func(void) { int a 0; // 存栈Stack函数调用时创建退出直接销毁 a; printf(%d , a); }调用多次输出1 1 1 1内存栈每次调用重新初始化为 0函数结束销毁。2. static 局部变量c运行void func(void) { static int a 0; // 存.bss/.data段只初始化1次 a; printf(%d , a); }调用多次输出1 2 3 4核心特性初始化仅执行 1 次程序上电第一次进函数才赋值后续调用保留上次值内存不在栈在全局 RAM (.bss/.data)函数退出不会销毁生命周期 整个程序运行作用域仅限当前函数外部其他函数无法访问变量a单片机优势不占用栈空间递归 / 循环不会栈溢出。二、场景 2修饰全局变量函数外部1. 普通全局变量c运行int g_val 10; // 存.data段整个工程所有.c文件都能extern访问工程任意文件写extern int g_val;就能跨文件读写。2. static 全局变量c运行static int g_val 10; // 存.data段仅限当前.c文件使用核心特性内存区域不变仍在.data/.bss程序全程存在文件作用域隔离其他.c文件无法通过extern引用杜绝跨文件重名冲突单片机项目规范所有模块内部全局缓冲区NTC 数组、缓存全部加 static。三、场景 3修饰函数1. 普通函数c运行void TestNtc(void) { }整个工程任意文件都能直接调用。2. static 函数c运行static void TestNtc(void) { }核心特性仅限当前.c 文件调用外部文件无法引用模块化隔离只给本文件内部使用的工具函数全部加 static防止全局函数名泛滥链接时不会导出符号固件体积轻微减小。四、static 内存分布汇总表表格写法内存区域生命周期作用域函数内int a栈 Stack函数单次调用仅当前函数函数内static int a.bss/.data整个程序运行仅当前函数文件外int g_a.bss/.data整个程序运行全工程所有文件文件外static int g_a.bss/.data整个程序运行仅限当前.c 文件普通函数void func()代码段 Flash程序运行全工程可调用static void func()代码段 Flash程序运行仅限当前.c 文件五、结合 NTC 单片机代码实战例子例 1static 局部变量滤波计数保留上次值c运行uint16_t Ntc_GetAdc(void) { static uint16_t filter_buf[8]; // 静态数组不占栈保存历史采样 static uint8_t idx 0; uint16_t adc ADC_Read(); filter_buf[idx] adc; idx % 8; // 均值滤波计算... }不加 static 的话filter_buf在栈数组大了直接栈溢出。例 2static 全局表NTC 码值表仅 ntc.c 内部使用c运行// ntc.c 文件内其他文件无法访问这个表 #ifdef NTC_R_10K static const uint16_t ntc_code[] {0x01C4,0x023B,...}; #elif defined(NTC_R_100K) static const uint16_t ntc_code[] {0xXXXX,...}; #endif例 3static 内部工具函数仅 ntc.c 内部调用c运行// 查表转换温度外部文件不能调用 static int Ntc_CodeToTemp(uint16_t adc) { // 二分查表逻辑 } // 对外提供的接口不加static其他文件可调用 int Ntc_GetTemp(void) { uint16_t adc Ntc_ReadAdc(); return Ntc_CodeToTemp(adc); }六、高频易错点static const常量全局static const存.rodata只读 Flash不占 RAM函数内static const同样存在只读区不会每次进函数重复分配。static 局部变量初始化只一次c运行static int a 10; // 仅上电执行一次 a 10; // 每次调用都会重新赋值覆盖记忆值栈溢出解决方案大数组、缓冲区全部用static修饰转移到全局 RAM不占用栈。模块化规范模块私有变量 / 工具函数全部加static对外接口、跨文件变量不加 static。总结函数内 static 变量保值、不占栈、生命周期全局全局 static 变量 /static 函数锁死在当前文件外部不可访问。