C语言基础学习笔记(7):变量的存储类型
Guderian出品
什么是变量的存储类型
变量的存储类型:即编译器为变量分配内存的方式,决定了变量的生存期(Lifetime)。在静态存储区中分配内存的变量生存期是整个程序,全程占据内存;在动态存储区中分配内存的变量生存期是定义它的语句块。声明的方法是:存储类型 数据类型 变量名;
。
编译器如何给变量分配内存
编译器通过将变量名映射到不同的内存地址来实现作用域的划分,如全局变量位于RAM
中的静态存储区,局部变量位于RAM
中的动态存储区。
(1)只读存储区
- 存放机器代码和常量等只读数据
(2)静态存储区
- 存放全局变量和静态变量等
- 静态——发生在程序编译或链接时
(3)动态存储区
- 包括堆和栈。其中栈用于保存函数调用时的返回地址、形参、局部变量等
- 动态——发生在程序载入和运行时
变量的四种存储类型
auto(自动变量)
auto
型变量属于动态存储类型变量,系统调用函数时临时分配内存空间,函数执行结束就释放。大多数情况下定义自动变量时可以省略auto
,定义一个没有声明存储类型的变量,系统会缺省地认为这是一个自动变量。如:
int a
$\Longleftrightarrow$auto int a
static(静态变量)
从程序运行区占据内存,程序退出时释放内存。包括静态局部变量和静态全局变量。static
变量的使用会损害程序的可读性,因此在能够满足算法功能的前提下尽量少用。
静态局部变量
静态局部变量在函数执行结束时内存不被释放,函数下次执行变量的值不改变。如:
1 |
|
输出为:
1 | 1 |
静态全局变量
C
语言编程涉及多文件结构时,每一个.c
程序中的全局变量都可以被其他程序所调用。然而不同.c
程序中的全局变量有可能重名,在调用同名全局变量时会导致错误的产生。因此,在使用全局变量时,为了保证该全局变量只能在本程序文件中被调用,可以把该全局变量声明为static
类型。尽管如此,为了降低程序的耦合性,提高内聚程度,还是应该尽量减少全局变量的使用。
register(寄存器变量)
相当于把一个auto
类型的变量放入了CPU
的寄存器中(而非内存中)。这么做的好处是读写该变量的速度大大加快(如控制循环语句的i
,j
.k
等需要频繁读写的变量),但是众所周知CPU
的寄存器空间很小,不能把大量变量放入CPU
的寄存器中。
事实上,现代编译器会自动对我们写的代码进行优化,自动把需要提高读写速度的变量放入CPU
寄存器中,无需我们手动声明。总之,没必要过于强调其作用。
extern(外部变量)
如果我们想在全局变量的定义点前或在其他文件中访问这个变量,就要用到extern
类型变量。extern
变量的使用会损害程序的可读性,因此在能够满足算法功能的前提下尽量少用。
在全局变量的定义点前访问变量
1 |
|
在其他文件中访问本文件的全局变量
正确但不规范做法
在同一个工程项目中,有两个文件main.c
和a.c
。main.c
想要访问main.c
中的a
变量:
main.c
文件:
1 |
|
a.c
文件:
1 | int a = 1; |
正确且规范做法
在同一个工程项目中,有三个文件main.c
、a.h
和a.c
。main.c
想要访问main.c
中的a
变量:
main.c
文件:
1 |
|
a.h
文件:
1 | extern int a; |
a.c
文件:
1 |
|
【更多C语言系列】