static是C语言中的一个关键字,可以用来修饰变量(全局变量和局部变量),以及函数。下面是本人的一些拙见。
1.修饰局部变量
首先来看下面一段代码
#include<stdio.h>
void test()
{
int a = 1;
a++;
printf("%d ", a);
}
int main()
{
int i = 0;
for (i = 0; i < 5; i++)
{
test();
}
return 0;
}
这段代码的运行结果是这样的:
当我在函数test()内部定义a时在前面增加一个static
#include<stdio.h>
void test()
{
static int a = 1;
a++;
printf("%d ", a);
}
int main()
{
int i = 0;
for (i = 0; i < 5; i++)
{
test();
}
return 0;
}
这段代码的运行结果则是这样的:
比较一下,只是在创建局部变量的时候加了一个static,结果的差异却如此的大,这是为什么呢?
我们知道,局部变量的作用域是所在的局部区域,进入该区域创建,出该区域销毁,这也决定了他的生命周期。当局部变量被static修饰了以后,局部变量的作用域不变,进入该作用域创建,但是出该作用域不会被销毁,这在一定程度上可以说是延长了他的生命周期。那么为什么会出现这种结果呢?这就涉及到内存的相关问题,下面我们来简单地画一下:
首先,内存可以被简单地划分为栈区,堆区和静态区。栈区用来存放局部变量,堆区用于动态内存分配,静态区用来存放全局变量和static修饰的静态变量。一个局部变量本来是应该存放在栈区的,但是当他被static修饰了以后,他就被存放在了静态区。也就是说,本质上是局部变量的存放位置发生了改变。你想想,全局变量就是存放在静态区的,那么当局部变量也被存在静态区以后,生命周期延长也就不难理解了,此时局部变量的生命周期也是整个程序的生命周期。但是注意,仅仅是生命周期发生了改变,作用域并未改变。
修饰全局变量:
在一个工程的add文件下创建了一个全局变量a
在同一个工程的test文件下写一个main函数,使用到了这个全局变量
下面我们来看运行结果
大家知道全局变量的作用域是整个工程,以上代码就证明了这一点,其中extern是C语言中的另一个关键字,用于声明变量或函数,通俗点讲,就是告诉编译器这个变量或函数存在。
那么如果我在创建全局变量的时候加一个static修饰呢?
以上我只修改了add文件,并未修改test文件,下面我们来看运行结果:
出乎意料,竟然报错了。错误类型时link错误,说明在test文件中无法使用add文件中定义的全局变量。表面上看,是被static修饰的全局变量的作用域变小了,实际上,是static改变了全局变量的链接属性,将其外部链接属性改成了内部链接属性,使得这种全局变量只能在本文件中使用,而不能被另一个文件检测到。
修饰函数
首先二话不说上代码
仍然在add文件里定义一个函数,这个函数的功能是求两个数的和
然后是在test文件中调用这个函数
我们看结果
这说明函数同样可以跨文件使用,那么当我们在定义函数的时候加上一个static呢?
同样的,我只修改了add文件,看运行结果
和刚才一样,报了链接错误,这说明static修饰函数和修饰全局变量的效果是相似的。
总结一下:
1.static可以修饰局部变量,使其生命周期变长,而作用域不变,本质上是改变了局部变量的存储方式
2.static可以修饰全局变量,使其作用域变小,而生命周期不变,本质上是改变了链接属性。
3.static可以修饰函数,同样使被修饰的函数不能跨文件使用。