C语言中变量的作用域、生存期、存储类型、内存空间分布
一、变量的作用域:
C语言中根据变量作用域的不同将变量分为局部变量与全局变量。
1、局部变量:
在函数体内部或者在复合语句内部定义的变量,只在函数体内部或者复合语句内部有效的变量称为局部变量。
2、全局变量:
在函数体外部定义的变量称为全局变量,全局变量可以被本文件中的其他函数所调用。它的有效作用域是从
全局变量的定义位置开始直到本源程序文件的结束。不要误认为全部变量的作用域在整个源文件内有效,那是因为
我们习惯于把全局变量定义在源文件的开头。
注意:
如果一个源程序文件内全局变量与局部变量同名,那么在局部变量的作用域内,局部变量有效,全局变量被“屏
蔽”;或者定义在函数开头的局部变量与定义在复合语句内部的局部变量同名,则在局部变量的作用范围内,同名的
复合语句内定义的局部变量有效,函数开头定义的局部变量被“屏蔽”。
二、变量的存储方式和生存期
1、变量的存储方式
从作用域的角度可以将变量分为局部变量和全局变量。而从变量的存储方式上可以分为静态存储方式和动态存
储方式。静态存储方式是指程序运行期间由系统分配的固定的存储空间的方式;而动态存储方式则是程序运行期间
根据需要进行动态的分配存储空间的方式。
静态存储区和动态存储区存放的数据类型:
静态存储区主要存放的是全局变量和静态局部变量,而动态存储区存放的是非静态局部变量和通过malloc、new
获取的内存空间,即动态栈和动态堆。
2、变量的存储类型
在C语言中变量主要有一下四种存储类别:auto、static、extern、register
1、auto存储类型:
auto关键字一般省略,变量默认的存储类型就是auto。当auto修饰全局变量未初始化时默认为0,所有的全局
变量都存放在静态存储区;auto修饰局部变量未初始化时默认为随机值,此时存放在动态存储区的动态栈中。
2、static存储类型:
(1)static可以修饰全局变量、局部变量、函数,修饰不同的内容时作用效果不同。
(2)static修饰全局变量时,用于限制全局变量的作用域,使其只在本文件中有效,不可以被其它文件所引用;
(3)static修饰局部变量时,用于延长局部变量的生存期,使其以静态存储的方式存放在静态存储区,它在编译
时进行初始化,且只初始化一次。static局部变量的值在调用结束后不消失,而继续保持原值,其占用的存储单元
不释放,在下次调用时,使用上次调用结束后变量的值。
(4)static修饰函数时,表示禁止其它文件调用该函数。
例1、 例2、
int i = 1; int i = 1;
while(i < 5) while(i < 5)
{ {
int a = 0;/*每次调用都初始化*/ static int a = 0;//只在编译时初始化一次
a++; a++;
printf("%d\t", a); printf("%d\t", a);
i++; i++;
} }
结果:1 1 1 1 结果:1 2 3 4
3、extern存储类型:
extern关键字主要用于修饰全局变量和函数。当修饰全局变量时它可以扩展全局变量的作用域:在一个文件内
部扩展全局变量的作用域或者将全局变量的作用域扩展到其它文件中;当extern修饰函数时,在其它文件中可以引
用被extern声明的外部函数。
4、register存储类型:
register修饰的变量表示寄存器变量,主要是提高运行效率,但是不建议使用,因为比较危险,这里不做过多介绍。
三、C语言中内存空间分布
栈区 | 存放局部变量,由操作系统来进行动态的分配/回收内存空间 | 读写权限 |
---|---|---|
堆区 | 手动申请、手动回收,通过malloc函数或者new、delete运算符 | 读写权限 |
.data | 存放已经初始化的静态局部变量和全局变量 | 读写权限 |
.bss段 | 存放未初始化的静态局部变量和全局变量 | 读写权限 |
.rodata段 | 存放一些常量,如字符串常量 | 只读权限 |
代码段 | 存放可执行代码 | 只读权限 |
.bss段和.data段主要存放的是静态局部变量和全局变量,因此他们属于静态存储区。
注意:C语言的内存空间分布中没有静态栈,不要把这里的动态栈与数据结构中的动态栈和静态栈混淆。
栈区和堆区是运行时分配;其他区域在编译时已经进行了分配。