跳转至

static 在嵌入式 c 可以怎么用

这篇文章,想讲一讲 static 在嵌入式 c语言 中的用法。嵌入式中,static 初学时很少会有人用,大家都是一个文件中定义全局变量,就没有管特别细节的东西。

我这里说 3 个例子,但是我觉得最有用的就是控制符号可见性。

控制符号可见性

这个内容,可以有这样一个场景:比如你写了一个模块,解析某个传感器传回来的信息,然后你在模块中定义了一些全局变量,如 RX_BUFF 存储接收字节,state 啥的处理接收状态,然后你想把这个功能移植到另外一个项目中去,但是你的这个新项目里面,你在之前已经定义过一些全局变量名,如 RX_BUFF。这时候,是不是就会报编译错误。这时候就需要用到 static。

因为在嵌入式工程中,一个项目通常由多个 .c 文件共同组成。当多个文件一起编译时,未使用 static 修饰的全局变量和函数会被编译器导出为全局符号,链接器可以在其他文件中找到它们。

例如,在 led.c 中定义的 LED_Init() 函数,只要没有加 static,其他文件就可以通过头文件声明后调用。

相反,如果使用 static 修饰,则表示该变量或函数只在当前 .c 文件内部可见,其他文件无法访问。

实际开发中,通常将需要被其他模块调用的接口函数定义为全局函数,而将模块内部使用的变量和辅助函数定义为 static,这样可以避免命名冲突,提高代码的模块化和可维护性。

像我们这个模块例子,如果你在初始设计的时候,把 RX_BUFF 设置成 static ,那么,是不是就算你移植进其他项目中,他也不会在编译的时候被编译器到处为全局符号。就不会影响到原来的工程。

改变变量生命周期

static 除了可以限制变量和函数的作用范围外,还具有保持变量生命周期的作用。

其实主要就是你想在某个函数中定义一个有类似全局属性的变量就能使用 static 在函数内定义,定义的这个变量也不能被其他函数调用。

普通局部变量在函数执行结束后会被释放,而使用 static 修饰的局部变量会存储在静态存储区中,只在程序启动时初始化一次,并且在后续函数调用过程中一直保留之前的值。

例如,一个计数函数中的 static 变量,每次调用都会在上一次结果的基础上继续累加。

需要注意的是,静态存储区中的变量主要包括全局变量和 static 变量,它们的生命周期都贯穿整个程序运行过程,但 static 可以进一步限制变量的可见范围。因此,在嵌入式开发中,static 常用于保存模块内部状态,同时避免变量被其他文件访问。

静态存储区初始化

static 修饰的变量还有一个特点,就是系统会默认将其初始化为 0。

因为 static 变量存储在静态存储区,而静态存储区中的内存在程序启动时会被系统自动清零,所以如果没有手动赋值,变量默认值就是 0。

需要注意的是,全局变量同样具有这个特点,因为全局变量也存储在静态存储区中。

例如,定义 static int count; 后,即使没有初始化,count 的初始值也是 0。