C++面向过程与static关键字

(一)隐藏

在我们进行多文件操作时,没有加static的全局变量和函数都具有全局可见性,即在每个文件中都可以使用,如果我们加了static,就会对其它源文件隐藏,即只可在本文件中使用,利用这一特点可以在不同的文件中定义同名函数和变量,而不需要担心命名冲突。下面我们举例看看。

这是一个全局变量:

int a = 5;

这是一个静态全局变量:

static int a = 5;

静态全局变量的特点:
(1)该变量在全局数据区分配内存;
(2)未经初始化的静态全局变量会被程序自动初始化为0;
(3)静态全局变量在声明它的整个文件都是可见的,而在文件之外是不可见的;

这是一个普通函数:

void fn();
void fn() {
    int n = 10;
    cout << n << endl;
}

这是一个静态函数:

static void fn();
void fn() {
    int n = 10;
    cout << n << endl;
}

定义静态函数的特点:
(1)静态函数不能被其它文件所用;
(2)其它文件中可以定义相同名字的函数,不会发生冲突;

非常显然,定义静态全局变量和静态函数只要在声明前面加上static关键字就行了,他们和普通全局变量和普通函数唯一的最大的区别就是不能再声明以外的的文件中使用。

(二)改变生存期

存储在静态数据区的变量会在程序刚开始运行时就完成唯一的一次初始化。静态存储区的两种变量:全局变量和static变量。与全局变量相比,static可以控制变量的可见范围。如果static局部变量在函数内定义,它的生存期为整个源程序,但是其作用域仍与普通变量相同,即只能在定义该变量的函数内使用。退出该函数后,该变量还继续存在,但我们不能使用它。
静态局部变量保存在全局数据区,而不是保存在栈中,每次的值保持到下一次调用,直到下次赋新值值才会被修改成新的赋值。

我们可以先看这个案例:

#include<iostream>
using namespace std;

void fn();

int main(void){
    fn();
    fn();
    fn();
}

void fn(){
    static int n = 10;
    cout<<n<<endl;
    n++;
}

大家可以试着运行这个程序看看结果,是不是和你想的不太一样呢?

这个例子就使我们想到一个问题,有时候我们需要在函数的两次调用之间对变量的值进行保存,我们通常的想法是定义一个全局变量来实现。但是,如此一来变量已经不再属于函数本身了,会给程序的维护带来不便。而静态局部变量正好可以完美的解决这个问题。

静态局部变量的特点:
(1)该变量在全局数据区分配内存;
(2)静态局部变量在程序执行到该对象的声明处时被首次初始化,即以后的函数调用不再进行初始化;
(3)静态局部变量一般在声明处初始化,如果没有显式初始化,会被程序自动初始化为0;
(4)它始终驻留在全局数据区,直到程序运行结束。但其作用域为局部作用域,当定义它的函数或语句块结束时,其作用域随之结束;

最后总结一下:首先static的最主要功能是隐藏,其次因为static变量存放在静态存储区,所以它具备持久性和默认值0.

好了,本教程就到此结束啦,喜欢的小伙伴记得点赞哦,也欢迎志同道合的朋友们关注我和我一起交流。

2019年4月16日