static是一个常见的关键字,今天来分享一下我对static的理解。
static即静态修饰,修饰局部变量可以改变局部变量的生命周期以及存储方式,普通局部变量,在函数结束之后,自然的由编译器回收资源,而static修饰的局部变量会在初次调用函数时创建此变量,并且在整个程序的运行期间都持续的存在,在函数结束之后并不会被销毁,在下一次调用时,该变量仍然保持上次调用后的状态,这种特性使得static局部变量可以既不暴露给全局,只有此函数可以改变这个变量,又保持数据的持久化,可以产生累计的效果。
/*static局部变量和普通局部变量的区别*/
#include <stdio.h>
int fun1()
{
//static局部变量
static int num = 0;
return num++;
}
int fun2()
{
//普通局部变量
int num = 0;
return num++;
}
int main()
{
for(int i = 0; i != 5; i++)
{
printf("%d\n",fun1()); // 0 1 2 3 4
printf("%d\n",fun2()); // 0 0 0 0 0
}
}
static修饰全局变量或者函数,可以改变全局变量或者函数的可见性,只有本文件中可见,避免了全局空间的污染,这样的static全局变量或者函数只能在它定义的这个文件内被访问,无法从其他源文件中进行直接的调用,这有利于提高代码的封装性和模块化程度。
/*static修饰全局变量和函数*/
/*main.c*/
//普通函数
void fun(){}
//普通全局变量
int num = 0;
int main(){}
/*fun.c*/
//static全局变量
static int num = 0;
//static函数
static void fun(){}
以上两个文件同时编译时,由于fun.c中与main.c同名的全局变量和函数是用static修饰的,因此只有在fun.c中可见,不会产生冲突,保证了fun.c中num的独立性。
static修饰类中的成员变量或者成员函数,可以使成员变量或者成员函数脱离对象直接使用类名加作用域限定符进行访问,本质上也是因为static改变了成员变量和成员函数的生命周期和存储位置。
class ClassA
{
public:
static int num1;
int num2 = 0;
static void fun1(){}
void fun2(){}
}
//静态成员变量类内声明,类外定义
static int ClassA::num1 = 0;
int main()
{
//静态成员函数调用方式
ClassA::fun1();
//普通成员函数调用方式
ClassA a;
a.fun2();
//对成员变量进行操作
a.num1++;
a.num2++;
cout << a.num1 << a.num2; // 1 1
//静态成员变量保持了数据的持久化
ClassA a1;
cout << a1.num1 << a.num2; // 1 0
}