变量的存储方式
前面我们说过,变量根据位置的不同
,分为不同的作用域
。今天我们通过变量存在的时间
来观察变量的存储方式
。
动态存储方式和静态存储方式
有的变量是在程序运行过程中一直存在
,有的则是在调用其所在的函数时才临时分配存储单元,而在函数调用结束后
,该存储单元就马上释放
了,变量不存在了。综上,我们发现变量根据存在时间的不同,分为动态存储方式
和静态存储方式
两种。
静态存储方式:是指程序在运行期间,由系统分配固定的存储空间
。
动态存储方式:是指程序运行期间根据需要进行动态的分配存储空间的方式。
不同存储区域下数据的存储和释放
在内存中,可以供用户使用的存储空间分为一下三种:
在程序执行过程中,全局变量
一直占用着固定的存储单元
,并不是动态的进行分配和释放
的。
在动态存储区域
,常见的有:
- 函数的
形参
。在调用这个函数时,给形参分配存储空间 - 函数中定义的,没有用 static 声明的
自动变量
(后面会写) - 函数调用时的
现场保护
和返回地址
等。
上面这些数据,在函数调用开始时
分配动态存储空间
,在函数结束时释放
这些空间。在程序的执行过程中,这种分配和释放
是动态进行
的。
因为是动态进行的
用完就释放
,所以程序如果两次调用一个函数,那么函数中的变量地址可能是不同的。
总结
所以,如果一个程序包含若干函数,每个函数中
的局部变量的生存期
并不等同于整个程序的执行周期
。因为局部变量的生存期
是随着函数被调用
的开始和结束来进行分配和释放的
。
在 C 语言中,每一个变量和函数都有两个属性,数据类型
和数据的存储类别
。
数据类型:诸如
浮点型
、字符型
、整型
等等。
数据存储类别:动态存储、静态存储等等
你知道吗?
其实在定义和声明变量或者函数时,一般应同时指定其数据类型和存储类型,也可以采用默认方式指定。也就是如果用户不指定,系统会自动指定一种存储类型。
局部变量的存储类别
C 的存储类型包括4中,自动的(auto)、静态的(static)、寄存器的(register)、外部的(extern)。
存储类别声明的一般形式
存储类别 数据类型 变量名;
自动变量(auto 变量)
在函数的局部变量中,如果不专门声明为静态(static)
存储类别,则都是动态的进行分配存储空间的,数据存储在动态存储区。
在函数中的形参、函数中定义的局部变量、函数中复合语句定义的局部变量,都属于此情况
在函数被调用时,系统会给这些变量分配存储空间,在函数调用结束后,会自动释放这些存储空间,因此这类局部变量称为自动变量。自动变量用关键字auto
来进行存储类别的声明。
1 | int test( int a){ |
上面的 a 是形参,b 和 c 是自动变量,所以执行玩 test 函数后,系统会自动释放 a、b、c 三个变量。
自动变量是我们使用最多的,前面我们没有特别的声明变量为自动变量是因为,
int a
和auto int a
其实是等价的,所以auto
关键字可以省略
。
静态局部变量(static 局部变量)
有时候我们也会遇到这种情况,希望在函数的局部变量
中,在函数调用结束后
,变量值继续保留,也就是其占用的存储单元不要释放
,在下一次调用该函数的时候,函数内的这个局部变量就是上次调用结束后的值
,这就是静态局部变量
例子
1 |
|
上面的例子中,我们定义了三个变量,一个在 main 函数中,一个在自定义函数中,还有一个是 static 静态变量。我们在 main 函数中让一个自定义函数执行3变,并且输出值。看看发生了什么变化。
输出结果是:
6
7
8
Program ended with exit code: 0
我们发现,在自定义函数 test 中,b 和 c 都执行了自身+1的操作,但是结果只有静态变量 c 保留了自身的值
,并且输出了出来。
总结
根据上面的例子我们发现:
静态存储变量
属于静态存储类别
。在静态存储区内分配存储单元,在整个程序执行期间都不释放
。自动变量
属于动态存储类别
,在动态存储区分配存储单元,函数调用结束后释放
。静态局部变量
在编译是赋初值,即赋初始值只有一次
。变量会保留上次调用函数结束时的值
。而对动态局部变量
来说,赋值不是随着编译进行的,而是在函数被调用的时候才会赋值,并且每调用一次就重新赋值一次。- 如果
编译时
,静态局部变量没有赋值
的话,那么编译时则会自动获取一个静态局部变量
初值0
,如果是字符变量则是\0
。如果是自动变量
的话,它的初值不确定
。因为调用时才会分配存储单元,没分配时,变量值不确定。 静态局部变量
只是变量存在的时间改变了
,并不改变变量作用域,因为是局部变量
,所以只在该函数内才能调用
。
静态局部变量虽然方便,但是会影响程序的可读性,多次运行后弄不清变量当前的值是什么,所以不是必要的情况下,不要使用。
尾巴
这是我的个人学习笔记,主要是应付考研复习使用,充斥着一些吐槽和个人观点,并不严谨,欢迎大家参考、指正。