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

学嵌入式和C语言编程|学习日记Day11:各类数组作函数参数、变量作用域、生命周期、存储类别

前言

今天继续拓展函数传参,学习一维字符数组、二维整型数组、二维字符数组作为函数参数的规则;然后学习变量的作用域、生命周期,还有autostaticregisterextern四种存储类型。
在嵌入式开发当中,局部、全局、static 静态变量使用频率非常高,直接关系到外设状态保存、多文件工程开发,是嵌入式 C 的核心重点。

一、不同数组作为函数参数

1. 一维字符型数组做函数参数

函数定义格式

c
返回值 函数名(char 数组名[])
{
//函数体
}

调用格式

c
函数名(数组名);

注意要点

  1. 一维字符数组传参只传递数组名即可,不需要传入长度;字符串末尾自带'\0'结束标记,函数内部依靠\0判断字符串结束。
  2. 本质传递依旧是数组首元素地址,函数内部修改数组内容,外部原始数组会跟着改变。
  3. ⚠️在被调函数内部执行sizeof(数组形参),得到的是地址所占内存大小,不是数组真实总字节。

2. 二维整型数组做函数参数

函数定义格式

c
返回值 函数名(int 数组名[][列数], int 行数)
{
//函数体
}

调用格式

c
函数名(数组名, 行数);

注意要点

  1. 二维整型数组传参,形参列数必须写明,行数可以省略
  2. 函数内部无法通过sizeof自动计算行数,行数需要当做实参手动传入;列数可以在函数内通过sizeof(a[0]) / sizeof(a[0][0])计算得到。

3. 二维字符型数组做函数参数

函数定义格式

c
返回值 函数名(char 数组名[][列数], int 行数)
{
//函数体
}

调用格式

c
函数名(数组名, 行数);

各类数组传参汇总表

数组类型

函数形参写法

是否需要传入长度

传递本质

一维 int 数组

int arr[] , int len

✅必须传入数组长度

首元素地址

一维 char 数组

char str[]

❌不需要,依靠\0结束符

首元素地址

二维 int 数组

int arr[][列] , int row

✅传入行数;列数代码内计算

数组首行地址

二维 char 数组

char str[][列] , int row

✅传入行数

数组首行地址

二、变量的作用域(空间角度)

作用域:标识符、变量能够被访问、使用的代码范围。

  1. 局部作用域:写在大括号{}内部,函数内部定义的变量、形参,只能够在大括号内部访问。
  2. 全局作用域:写在所有函数外面,整个工程都可以访问,例如函数名、全局变量。

嵌套作用域规则:如果内外出现同名标识符,外层变量在内层不可见(就近原则)

语法强制要求:变量必须先定义,后使用;同一个作用域,不能定义名字相同的变量。

三、变量的生命周期(时间角度)

生命周期:变量内存开辟,直到内存被回收的完整存活时间。

  • 动态生命周期:局部变量。走到变量定义处开辟内存;离开作用域,内存立刻回收。
  • 静态生命周期:和整个程序运行时间保持一致。程序启动开辟内存,程序结束才释放内存。全局变量、static 静态变量属于静态生命周期。

局部变量、全局变量、static 静态变量对比

变量类型

作用域

生命周期

存储位置

未初始化默认值

局部普通变量

仅限当前大括号内部

动态生命周期,出作用域销毁

栈区

随机垃圾值

全局变量

整个程序全局可见

静态生命周期,程序结束销毁

数据段 /.bss 段

系统默认 0

static 局部静态变量

仅限局部大括号内部

静态生命周期,程序结束销毁

数据段 /.bss 段

系统默认 0

补充:

  1. 未初始化的全局变量、static 静态变量存放在.bss段,系统自动清零;
  2. 已经初始化完成的全局、static 静态变量存放在.data段。

四、四种存储类型修饰符

完整格式:存储类型 数据类型 变量名;

1. auto

  • 默认存储类型,日常写局部变量默认就是 auto,一般省略不写。
  • 具备局部变量动态生命周期,存储在栈区。

2. static 静态修饰符

static 有三层作用

  1. 修饰局部变量:变量变成静态生命周期,依旧保留局部作用域,出大括号不会销毁,值会保留。
  2. 修饰函数:该函数只允许当前.c 源文件内部调用,别的源文件无法访问。
  3. 修饰全局变量:该全局变量仅限当前源文件内部使用,外部其他.c文件无法访问。

嵌入式常用场景:按键计数、状态标记,用 static 局部变量保存上一次状态,函数多次调用之间保留数值。

3. register 寄存器变量

  1. 只是给编译器建议:尽量把该变量放到 CPU 寄存器中,提升运行速度,不是强制命令。
  2. 寄存器没有内存地址,不能对 register 变量取地址&

4. extern 外部声明

  1. 修饰全局变量:声明外部别的.c文件定义的全局变量,允许本文件访问外部全局变量。
  2. 修饰函数:声明外部其他.c文件中的函数,本文件可以调用外部函数。

今日学习总结

  1. 一维字符数组传参不用传长度,依靠字符串结束符\0;二维数组传参,列数绝对不能省略
  2. 作用域看空间,生命周期看时间;局部变量栈区分配,出大括号销毁;全局、static 静态变量程序全程存在。
  3. static 修饰局部变量:作用域不变,生命周期改为静态,函数多次调用之间保留数值。
  4. static 修饰函数、全局变量,限制作用域为本.c文件;extern 用来引用别的文件的全局变量和函数,是多文件嵌入式工程必备语法。
  5. register 只是建议放寄存器,不能取地址;auto 是局部变量默认属性,通常省略。
http://www.jsqmd.com/news/1311446/

相关文章:

  • 天气预报总结
  • 家用艺术涂料选购与施工全攻略:新手也能避开90%的坑
  • 数据科学导论:从CRISP-DM到实战工作流的知识体系构建
  • AI插件重构软件价值链:从VSCode插件到SaaS安全的新范式
  • MiniMax H3 效果展示与能力评测大纲
  • 从零打造MP3播放器:Arduino/ESP32硬件解码与嵌入式音频开发实践
  • 2026年达州到周边县城长途搬家公司甄选参考:正规、透明与性价比分析 - 优质品牌商家
  • AI生成汇报级PPT难点与落地实践
  • 深入解析502 Bad Gateway:从原理到实战排查与预防
  • 2026抖店商品卡流量玩法:新店破零与自然流量增长实用技巧 - 抖大侠
  • 陶瓷基板浆料有机转水系转型方案|涂易乐分散剂解决团聚、针孔缺陷
  • 热继电器原理、选型与故障排查全解析:工业电机的可靠守护者
  • Altium Designer PCB层叠设计全解析:从核心概念到Gerber输出避坑指南
  • Unity WebGL项目适配微信小游戏:核心思路、适配层实现与性能优化实战
  • 如何高效向论文作者获取代码与数据:从准备到沟通的完整指南
  • 从光通量到光束角:专业解读灯具核心参数与场景化应用指南
  • 企业小程序定制开发选型指南:甄别靠谱开发团队的核心标准与避坑方案
  • VB6数据导出Excel:6种方法详解与高性能模块设计
  • 抖店一件代发订单处理全流程 物流同步与售后纠纷应对攻略 - 抖大侠
  • Java 异常②
  • 2026 年现阶段西昌评价高的商场拆除回收源头厂家格局重塑与选型新思路,开了二十年的老商场要拆了?原来旧设备还能变钱,不少人都不知道这回事-昝氏设备回收 - 鉴选官
  • 全球股王再次易主,你咋看待
  • 倒计时·DJS V2.8.3beta
  • 从电竞选手性格与团队环境看组织行为学与舆论管理
  • 天线核心参数全解析:从频率、增益到VSWR,硬件工程师选型指南
  • 移远ML302 CAT1模组实战:硬件设计、AT指令与低功耗优化指南
  • GD32移植CmBacktrace:ARM Cortex-M崩溃追踪与深度调试实战
  • C#从入门到精通:实战指南与上位机、WebAPI开发全解析
  • 如何让魔兽争霸3在2025年依然流畅运行:WarcraftHelper完整优化指南
  • Android 设备连接与边缘计算项目全景