浅谈静态局部变量
在学习静态变量中,我总结出3个会经常遇到的问题
1. 为什么静态局部变量的生命周期和全局变量一样都是整个程序执行过程,那为什么不能在其它的函数中访问这个静态局部变量?
2. 如果一个带有静态局部变量的函数被调用,不是每次都执行一次静态局部变量的声明代码吗?那为什么说静态局部变量只初始化一次呢?
3. 既然说静态局部变量的生命周期是整个执行过程,那如何在它的作用域外使用它呢?
下面我们就带着这3个问题去研究一下这3个问题(如有说错的地方,欢迎纠正)
什么是静态变量
静态变量的类型关键字是static。static局部变量叫做静态变量,它的生命周期是整个应用程序的运行时间,它只会被初始化一次。static声明的全局变量被缩小了作用域,它只能在所在文件中被使用。
所以静态变量分为静态全局变量和静态局部变量,静态全局变量的话只能在当前文件中访问,静态局部变量生命周期是整个程序运行期间。这次归纳的内容主要是静态局部变量。
不同层次的变量可以重名,在使用的时候变量名称匹配的是所有作用域包括使用,语句的变量中层次最深的。并且在这条语句之前声明的那个变量。
例 一 :
void func()
{
int a = 0;
static int b = 0;
}
在函数func里,变量a属于一个局部变量,a的生命周期是所在函数的执行过程,而a的作用域是所在函数的执行体代码。变量b是一个静态变量,b的作用域和a一样,但是b的生命周期是整个程序的运行期间。
如果在2个函数中都存在变量名b,那么这2个看上去一样的变量名,是分别代表2个不一样的存储区的,就像学生一样,2个名字相同的学生,他们也代表着不同的个体,代表着2个不一样的学号。为了避免出现1个变量名代表2个存储区的情况出现,所以在别的函数中,是没法用b这个变量名去找到func函数里面b的存储区的。
例 二 :
<pre name="code" class="cpp">#include <stdio.h>
//声明一个全局变量
int a = 0;
//声明一个函数,返回一个静态局部变了的地址
int* func()
{
//声明一个静态局部变量
static int b = 0;
return &b;
}
int main()
{
//再声明一个局部静态变量
static int c = 0;
//打印全局变量a,和main中c的地址
printf("a的地址是%p, c的地址是%p\n", &a, &c);
//声明一个指针变量存储func的返回值(返回的是func里面b的地址)
int *p = func();
int b;
//打印出func函数中b的地址,和main函数中b的地址
printf("p存储的地址是%p, b的地址是%p\n", p, &b);
return0;
}
以上是例二的运行结果,我们可以看出main函数的b和func函数中的b是代表真不同的存储区,而且a和c的地址不是连续的,中间还存在这一个4个字节的存储区,这个存储区就是是func函数中b的地址,但在打印出a,c地址之前,并没有调用过func函数。由此可以看出,静态局部变量是在程序开始的时候就已经分配了存储区的,并不是在调用函数的时候才分配存储区的,所谓的声明一个变量,就是分配一个存储区。我们可以当作静态局部变量的声明语句是在函数外面的,在例二中无论执行多少次func函数,也不会执行static int b = 0;这条语句的,因为这条语句真正执行的地方是在函数的外面,所以说静态变量只初始化一次。
如果在其它函数中使用静态局部变量,我们可以通过返回值的方式取得该静态局部变量的地址,就可以使用它了。
(仔细观察,不难发现自动变量和静态变量的地址,相隔有点远,是因为系统内存分配的问题,并不是巧合,有关于系统内存的知识,我会在不久将来整理出来(因为还没学啊))。