前言
static 是C语⾔中的关键字。
static 是 静态的 的意思,可以⽤来:
• 修饰局部变量
• 修饰全局变量
• 修饰函数
一、变量的作用域和生命周期
1.作用域
限定变量的可⽤性的代码范围就是这个变量的作⽤域。
(1)局部变量的作⽤域是变量所在的局部范围。
如下示例:
#include<stdio.h>
int main()
{
{
int a = 0;
printf("1 %d", a);
}
printf("2 %d", a);
return 0;
}
上面的程序中,只能执行第2个打印函数时会报错,因为定义的a变量作用只在大括号的内部。
(2)全局变量的作⽤域是整个⼯程(项⽬)。
如下所示:
#include<stdio.h>
int a = 0;
void test()
{
printf("3 %d\n", a);
}
int main()
{
{
printf("1 %d\n", a);
}
printf("2 %d\n", a);
test();
return 0;
}
定义的变量a为全局变量,在整个工程中都能使用。
2.⽣命周期
生命周期指的是变量的创建(申请内存)到变量的销毁(收回内存)之间的⼀个时间段。
(1)局部变量的⽣命周期是:进⼊作⽤域变量创建,⽣命周期开始,出作⽤域⽣命周期结束。
(2)全局变量的⽣命周期是:整个程序的⽣命周期。
二、static
1.static修饰局部变量
先给出如下两段代码:
代码1:
//代码1
#include <stdio.h>
void test()
{
int i = 0;
i++;
printf("%d ", i);
}
int main()
{
int i = 0;
for (i = 0; i < 5; i++)
{
test();
}
return 0;
}
代码2:
//代码2
#include <stdio.h>
void test()
{
//static修饰局部变量
static int i = 0;
i++;
printf("%d ", i);
}
int main()
{
int i = 0;
for (i = 0; i < 5; i++)
{
test();
}
return 0;
}
结果如下:
- 代码1的test函数中的局部变量i是每次进⼊test函数先创建变量(⽣命周期开始)并赋值为0,然后++,再打印,出函数的时候变量⽣命周期将要结束(释放内存)。
- 代码2中,我们从输出结果来看,i的值有累加的效果,其实 test函数中的i创建好后,出函数的时候是不会销毁的,重新进⼊函数也就不会重新创建变量,直接上次累积的数值继续计算。
以上两段代码的区别在于代码2中是用static修饰变量i。
- 结论
static修饰局部变量称为静态变量,在编译器编译代码时,就会为静态变量分配地址,而不是进入函数后创建这种变量。这就改变了变量的⽣命周期。但是作⽤域不变的。
使用建议:如果⼀个变量出了函数后,我们还想保留值,等下次进⼊函数继续使⽤,就可以使⽤static修饰。
2.修饰全局变量
全局变量默认带有外部链接属性,通过声明可以被其他源文件使用。而通过static修饰后的全局变量,外部链接属性就变成了内部链接属性,只能在⾃⼰所在的源⽂件内部使⽤了,其他源⽂件,即使声明了,也是⽆法正常使⽤的。
代码1:
代码2:
使⽤建议:如果⼀个全局变量,只想在所在的源⽂件内部使⽤,不想被其他⽂件发现,就可以使⽤static修饰。
3. static 修饰函数
其实 static 修饰函数和 static 修饰全局变量是类似的,⼀个函数在整个⼯程都可以使⽤,被static修饰后,只能在本⽂件内部使⽤,其他⽂件⽆法正常的链接使⽤了。
代码1:
代码2:
使⽤建议:⼀个函数只想在所在的源⽂件内部使⽤,不想被其他源⽂件使⽤,就可以使⽤ static 修饰。
总结
static修饰局部变量改变了变量的⽣命周期,但是作⽤域不变的;
static修饰全局变量会使全局变量的外部链接属性变成内部链接属性,只能在⾃⼰所在的源⽂件内部使⽤;
static修饰函数,使得函数只能在本⽂件内部使⽤,其他⽂件⽆法正常的链接使⽤了。