当前位置: 首页 > news >正文

C 语言 static的用法

static分三大使用场景:局部变量、全局变量、函数,作用核心只有两点:

  1. 修改存储周期:变量生命周期延长至整个程序运行期间
  2. 修改作用域(可见性):限制作用域仅当前.c文件内部

一、static 修饰局部变量(函数内部)

1. 普通局部变量 vs static 局部变量

void test() { int a = 0; // 普通局部变量:栈存储,函数调用结束销毁 static int b = 0; // static局部变量:静态存储区,程序结束才销毁 a++; b++; printf("a=%d, b=%d\n", a, b); } int main() { test(); // a=1, b=1 test(); // a=1, b=2 test(); // a=1, b=3 return 0; }

2. 核心特性

  1. 初始化只执行 1 次static int b=0;仅程序启动时初始化一次,后续重复调用函数不会重新赋值;普通变量每次进函数都重新创建赋值。
  2. 存储位置不同
    • 普通局部:栈(stack),函数退出释放,每次调用重新分配
    • static 局部:静态全局区(data 段),全局生命周期
  3. 作用域不变依然只能在当前函数内访问,外部无法读取 / 修改。
  4. 默认自动初始化为 0不写赋值static int x;,x 初始就是 0;普通局部变量不初始化是随机垃圾值。

3. 典型用途

  • 函数计数、记录上次调用状态、只初始化一次的缓存数据
// 只打印一次提示 void log_once() { static int flag = 0; if (!flag) { printf("程序启动日志\n"); flag = 1; } }

二、static 修饰全局变量(函数外部)

1. 不加 static 全局变量

// file1.c int num = 10; // 全局变量,外部文件可跨文件访问 // file2.c extern int num; // 声明后就能使用file1的num

2. 加 static 全局变量

// file1.c static int num = 10;
  • 作用域限制:文件内私有仅当前.c文件可见,其他.c文件用extern也无法访问、不能重定义同名变量。
  • 存储周期不变依旧存静态区,程序全程存在,默认初始 0。

3. 作用

多文件开发时,隔离文件私有全局变量,避免全局命名冲突

三、static 修饰函数(函数定义前)

// file1.c static void func() { printf("私有函数\n"); }
  1. 作用域限制:函数仅当前.c文件可用,外部文件无法调用,不能用extern声明。
  2. 用途:封装模块内部工具函数,对外隐藏实现,减少命名污染。
  3. 对比无 static 函数:普通函数是全局可见,全工程可调用。

四、static 三大场景对比总结表

修饰对象存储位置生命周期作用域初始化规则
普通局部变量栈 stack单次函数调用当前函数每次调用重新初始化,默认随机值
static 局部变量静态数据段整个程序运行当前函数仅初始化 1 次,默认 0
普通全局变量静态数据段整个程序运行整个工程所有文件程序启动初始化,默认 0
static 全局变量静态数据段整个程序运行仅当前.c 文件程序启动初始化,默认 0
普通函数代码段程序运行全工程可调用-
static 函数代码段程序运行仅当前.c 文件可调用-

五、常见易错点

1.static 局部变量的初始化不能放表达式里动态赋值

void test() { int n = 5; static int x = n; // 编译报错!static初始化必须是常量 }

2. static 变量不支持递归重置状态 递归调用同一个函数,static 变量会持续累加,不会每次递归清零。

3. static 不能修饰函数形参

void func(static int a) // 语法错误,不允许

4. 头文件定义 static 变量会出现多副本 如果在.hstatic int x;,每个包含该头文件的.c都会生成一份独立 x,互不干扰。

六、综合实战示例

示例 1:static 局部实现计数器

#include <stdio.h> int get_cnt() { static int cnt = 0; cnt++; return cnt; } int main() { printf("%d\n", get_cnt()); //1 printf("%d\n", get_cnt()); //2 printf("%d\n", get_cnt()); //3 return 0; }

示例 2:多文件 static 隔离(模块化)

// math.c static int cache = 0; // 仅math.c内部可用 static void reset() { // 内部私有函数 cache = 0; } int add(int a, int b) { cache = a + b; return cache; } // main.c #include <stdio.h> extern int add(int a, int b); int main() { printf("%d", add(2,3)); // cache、reset() 这里无法访问,编译报错 return 0; }

七、总结

  1. 函数内 static 变量:长存,只初始化一次,函数内独享;
  2. 文件外 static 全局 / 函数:私有,仅限当前.c,外部看不见。
http://www.jsqmd.com/news/1172524/

相关文章:

  • HBase 2.4 与 MySQL 8.0 大数据写入场景性能对比:单表亿级数据插入实测
  • PLSQL Developer 12 + Instant Client 11.2 配置:3个关键环境变量与1个TNS文件详解
  • TestStand 并行测试架构解析:4线程配置提升产线吞吐量 30% 实践
  • 浪琴官方服务项目及价格查询|详细地址及24小时售后热线权威信息通知(2026年7月最新) - 浪琴官方售后服务中心
  • 2026年7月最新西安宇舶官方售后客户服务电话及线下网点地址 - 亨得利官方服务中心
  • Unity Scroll View性能优化全攻略:从原理到实战解决动态列表卡顿
  • Claude Fable 5大语言模型:长任务处理与API配置实战指南
  • C++多线程编程:深入解析a++线程安全问题与std::atomic解决方案
  • C++ priority_queue自定义比较器:从函数对象到Lambda的深度解析
  • Java开发者实践RAG:从文档解析到向量检索的完整指南
  • 记录simulink与无人机的模型
  • 3个痛点,1个解决方案:Mac用户的局域网通信救星
  • 2026嘉兴GEO优化服务商实战评测:谁是源头实力派? - 品牌报告
  • 帝舵官方售后服务中心全部地址与热线实地考察报告+多信源验证(2026年7月最新) - 帝舵中国官方服务中心
  • 2026年7月最新惠州百达翡丽官方售后服务网点地址及客服电话一览 - 百达翡丽服务中心
  • 户外型微电网协调控制系统柜设计要点:防护等级与环境适配
  • 虚幻引擎XR开发实战:从蓝图到C++的跨平台沉浸式应用构建
  • C++ std::any_of:现代C++中高效检查容器元素存在性的声明式算法
  • Markdown + GitHub Actions:自动化生成动态 README 的 3 种实战方案
  • Unity灯光烘焙实战:从原理到应用,彻底解决DrawCall过高与卡顿问题
  • 欧米茄哪里买最便宜?售后维修保养全攻略权威公示(2026年7月最新) - 欧米茄服务中心
  • Fable游戏开发技术解析:从渲染优化到AI系统的工程实践
  • G26mos下沉视觉特效:实现原理、部署测试与性能优化指南
  • Unity音频系统全解析:从AudioSource到AudioMixer的实战指南
  • DVWA_File Inclusion
  • STM32+ESP8266 接入阿里云飞燕平台:MQTT 物模型 JSON 数据 5 步调试法
  • Conda 4.10+ 多用户服务器配置:3 种权限方案与 .condarc 路径优先级详解
  • 深圳百达翡丽回收价格查询及靠谱回收平台实测排行(2026年7月最新数据) - 诚收名表回收平台
  • 编程AI投票(在评论区说AI或编程)
  • 免费SQLite在线查看器:浏览器中直接探索数据库的终极指南