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

📅 2026/8/2 5:31:56 👁️ 阅读次数 📝 编程学习
学嵌入式和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 是局部变量默认属性,通常省略。