C语言中,变量存储类型指的是存储变量的内存的类型,主要分为三种:普通内存、运行时堆栈、硬件寄存器。
变量存储在那种类型的内存中和变量的作用域有很大的关系。
首先,分析一下变量的作用域。作用域与声明的位置有关。在一个源文件中,变量声明的位置有两种:在代码块内和代码块外。代码块指的是被花括号{}包围的一段代码。
(1)代码块外声明的变量都被称为静态变量,这些变量存储在静态内存中,不在运行时堆栈中。这些变量的作用域为:从声明位置起一直到源文件结束,存在于序执行的整个生命周期内,程序执行结束,静态变量才会被销毁。
(2)代码块内声明的变量被称为临时变量,缺省存储类型是auto,存在于运行时堆栈中。当代码块执行结束,这些变量就会被销毁。当一个函数被多次调用时,这些变量会被重新创建,但是变量所占据的内存位置可能与原来的位置不同,即使相同,这些新创建的变量也不是之前的变量。
如果给代码块内部声明的变量加上一个关键字static,那么它的存储类型就从auto变为static静态的,存储位置就会从运行时堆栈变到静态内存区域。但是这个变量的作用域仍然是代码块内部,只是当代码块执行完成之后还会存储在静态内存中,依然不能被代码块外部访问。
初始化
静态变量只会在声明的时候初始化一次,之后便不在初始化,而由于程序在链接的时候还无法判断自动变量的存储位置,因此只有当被调用时才会被初始化。
例子如下:
#include <stdio.h>
void test();
int c = 0;
int main() {
for (int i = 0; i < 4; i++)
{
test();
printf("In main c = %d\n", c);
c++;
printf("--------------------\n");
}
getchar();
return 0;
}
void test() {
static int a = 0;
int b = 0;
printf("In test a = %d\n", a);
printf("In test b = %d\n", b);
b++;
a++;
}
运行结果:
In test a = 0
In test b = 0
In main c = 0
--------------------
In test a = 1
In test b = 0
In main c = 1
--------------------
In test a = 2
In test b = 0
In main c = 2
--------------------
In test a = 3
In test b = 0
In main c = 3
--------------------
结果分析:
代码块外声明int c,为static 静态变量,存储于静态内存,程序运行时一直都在
代码块内声明static int a, 为static 静态变量,存储于静态内存,程序运行时一直都在
代码块内声明int b,为auto类型的临时变量,存储于运行时堆栈,test()执行完成之后被销毁
a,b,c初始化为0,当执行完一次for循环之后,a,b,c都变为1。不同的是test执行完一次之后就被销毁,因此b不存在了,而a和c保存在静态区域中,仍然存在;执行第二次for循环,b重新创建,为0;a,c不再被初始化,为1。所以打印出
In test a = 1
In test b = 0
In main c = 1
下面的for循环,每次b都被重新创建,所以值一直是0,而a,c不会,所以值会每次加1。