static
是C/C++语言中常见的一个关键字,就像int,break,while,for
等一样,都属于关键字。
在C语言中,static
被用来修饰变量与函数。其用法概括为以下三个方面:
static
修饰局部变量,使得局部变量成为静态局部变量。
那局部变量被static
修饰前后又有什么变化呢?上代码:
void test()
{
int i = 0; //局部变量i未被static修饰
i++;
printf("%d ",i);
}
我们知道,i
在test
里被定义,首先那就意味这i
的作用域仅在test
里,它在test
外并不能被使用。而且i
是在test
被调用的时候被定义生成,它会随test
的调用结束而被释放,换句话说也就是i
的生命周期取决于test
什么时候被调用,什么时候调用结束,当调用结束时,i
被释放,下一次再调用test
时,i
仍会被定义生成,不过此i
非彼i
,这时候的i
已经是全新的i
了。所以程序运行结果自然为全1。
现在我们用static
修饰一下局部变量i
:
void test()
{
static int i = 0;//局部变量i被static修饰
i++;
printf("%d ",i);
}
通过上面的对比,我们可以发现局部变量i
被static
修饰后(其余代码并没有发生变化),直接使得打印结果发生了变化。这是为什么?
原因在于static
修饰局部变量后,使得i的生命周期变为全局变量的生命周期,直接与主程序的运行与结束挂钩。但i
的作用域并没有发生变化,仍仅仅是test
里。具体解释起来:第一次调用test
时,局部变量i
被定义且初始化为0,打印一次,test
调用结束。注意注意!因为i被static
修饰,虽然test
结束,但i
并没有被释放。第二次调用test
时,因为此时这个i
在上一次并没有被释放,所以此次并不进行定义及初始化,即int i = 0;
被跳过,直接执行i++;
结果自然打印2。后面也是一样的道理,所以程序运行结果为1-10;
上述废话总结起来就一句话:static修饰局部变量,使得局部变量生命周期变成全局变量的生命周期,但作用域不变
static
修饰全局变量,使得全局变量成为静态全局变量。
惯例,看代码:
//add.c
int g_val = 2020;
//test.c
int main()
{
printf("%d\n",g_val);
return 0;
}
现在用static
修饰一下int g_val = 2020;
//add.c
static int g_val = 2020;
//test.c
int main()
{
printf("%d\n",g_val);
return 0;
}
总结一下:static修饰全局变量,使得全局变量作用域只限于当前文件,不可被跨文件使用。
static
修饰函数,使得函数成为静态函数。看代码:
//add.c
int Add(int x, int y)
{
return x + y;
}
//test.c
int main()
{
printf("%d\n", Add(2, 3));
return 0;
}
//add.c
static int Add(int x, int y)
{
return x + y;
}
//test.c
int main()
{
printf("%d\n", Add(2, 3));
return 0;
}
总结一下:static修饰函数,使得函数只限于当前文件使用,不可被跨文件使用。
C++中的static
作用不仅具有C语言中static
的特性,还有额外特性:
1.被static修饰的类成员函数不能被定义为虚函数
2.类的static成员属于类而不属于对象,即该类创建的所有对对象共享该成员
3.类中所有被static修饰的数据成员必须在类外初始化
4.类的static数据成员初始化默认值为0:因为static成员存储在静态变量区,而静态变量区内空间默认值一律为0
5.被static修饰的类成员函数仅能访问被static修饰的类成员数据与类成员函数