变量的存储位置
- 普通内存
- 运行时堆栈
- 硬件寄存器
变量的缺省存储类型取决于它的申明位置。
- 凡是在任何代码块之外声明的变量总是存储在静态内存中。不属于堆栈内存,这类变量称为静态变量。静态变量在函数运行之前创建。
- 在代码块内部声明的变量的缺省存储类型是自动的,存储在堆栈中。
对于在代码块内部声明的变量,如果给它加上 static 关键字,可以使它的存储类型由自动转变为静态。具有静态存储类型的变量在整个执行过程中一直存在。而不仅仅是它所在的代码块执行的时候存在。
注意:修改变量的存储类型,并不修改变量的作用域,它只是在该代码块内部按名字访问。
寄存器变量:register 关键字
明确两个概念:
- 存储类型:指该变量在地址空间的哪一个区域上存着。
- 作用域:该变量只能在哪些区域内被访问。比如,若某变量是全局的,则在整个代码区域中都可以被访问;若在函数内部,则只能在该函数内部被访问。
变量的初始化
如果不显式的初始化,静态变量的初始化为0;
而自动变量是不做任何初始化的,是随机值。
static 定义变量
#include <stdio.h>
static int m;
int fun1()
{
static int n = 0;
n++;
printf("n=%d\n", n);
}
int fun2()
{
m = 0;
m++;
printf("m=%d\n", m);
}
int main()
{
int i = 0;
for (i = 0; i < 5; ++i)
fun1();
for (i = 0; i < 5; ++i)
fun2();
return 0;
}
static 总结:
- 当 static 修饰全局变量或函数时,其变量存储类型和作用域都不变,只改变它的链接属性,将外部链接改为内部链接。也就是说变量或者函数只能在当前源文件中访问,而不能在其他源文件中访问。
- 当 static 修饰局部变量时,其变量的作用域和链接属性(只有内部链接)都不变,只改变它的存储类型(将类型从堆栈区变到静态区)。
变量的作用域、链接属性和存储类型总结
变量类型 | 声明位置 | 是否存储于堆栈 | 作用域 | 如果声明为static |
---|---|---|---|---|
全局变量 | 所有代码块之外 | 否 | 从声明到文件尾 | 改变了链接属性,不允许从其他文件中访问 |
局部变量 | 代码块起始处 | 是 | 整个代码块 | 存储类型从堆栈区变到静态区,它的值在整个程序的执行期一直保持 |
形式参数 | 函数头部 | 是 | 整个函数 | 不允许 |