文章参考与<零声教育>的C/C++linux服务期高级架构线上课学习
首先我们先介绍一下全局变量和局部变量,和static修饰变量的作用
局部变量:在一个函数的内部定义的变量叫局部变量,它的生命周期只限于当前函数。也就是说这个函数执行完return之后里边的的变量就会被回收,外部不能看到也不能使用
void fun(int value);
int main()
{
int n;
int m = 4;
fun(m);
return 0;
}
void fun(int value)
{
//这个函数内无法使用main中的n变量
int a,b;
//可以使用a,b,value
return ; //执行完这一指令a,b,value生命周期就已经结束
}
全局变量:在函数外定义的变量叫全局变量,它的生命周期和和有效范围是从声明这个变量开始位置到源文件结束(跨文件使用需要在想要调用这个全局变量的源文件中加上extern做一个全局变量声明,如果在某个函数中想引用后边的全局变量,和跨文件的一样)
int a ,b; //全局变量
void func()
{
a = 1; //使用全局变量
b = 2;
}
---------------------------------------------------------
extern int a,b; //记住这里不能直接初始化,这里只是引用声明后边的全局变量
//错误用法:extern int a = 0, b = 0;
void func()
{
//extern int a,b; 也可以在函数内部引用声明后边的全局变量
a = 8; b = 8; //使用全局变量
}
int a , b; // 真正定义全局变量的地方
全局变量有几点需要注意的地方:
0)使用全局变量需要注意,一经初始化分配内存生命周期就一直存在,直到整个程序结束
1)全局变量定义只能有一次(声明可以多次),位置是函数外,定义时会分配内存,也可以直接初始化。
2)在同一个源文件中,如果全局变量和局部变量同名,则在局部变量的作用范围,不会去影响全局变量
3)跨文件使用全局变量的extern关键词的用法,一般都是要求将extern说明放在源程序文件的开头(一般位于#include之后)。需要注意的是:使用这种跨文件的全局变量要很小心,因为某个源文件的某个函数中改变了这些全局变量的值,也会影响到其他源程序文件中使用该全局变量的值的函数
4)如果希望某些全局变量只能在当前源文件中被使用那么就用static来修饰
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
再来介绍一下内部函数和外部函数和static修饰函数的作用
内部函数:内部函数也被称为静态函数,只能在当前文件中使用。所以不同的源文件中使用了同名函数彼此不受干扰。如果希望本函数只能被当前源文件中的其他函数调用。那么定函数时,在最前边加上static关键字就可以:
static void fun(){}
外部函数:定义一个函数无需加static关键字。跨文件使用需要声明
//a.cpp
int fun(int a, int b)
{
//.....
return a + b;
}
----------------------------------------------
//b.cpp
int fun(int a, int b); //跨文件使用,需要声明a.cpp中的fun函数
int main()
{
int a = 0;
int b = 0;
int c = fun(a, b );
return 0;
}
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
再来看看static在类中又有什么作用:静态成员变量,静态成员函数
我们先来看一段代码:
class Time{
public:
int Minute; //普通成员变量
static int Minutes; //声明成员变量
static void fun(int value); //声明成员函数
};
//定义成员变量
int Time::Minute = 0;
//定义成员函数
void Time::fun(int value)
{
std::cout<< value << std::endl;
}
试着调用一下:
int main()
{
Time time1;
time1.Minute = 10;
Time time2;
time2.Minute = 30;
//可以看的出来上面两个对象的Minute是互不干扰的,初始化了两个对象,每个对象里边都有一个Minute,也就是可以理解成两个不同的变量,存储着两个地址
return 0;
}
那么如果有这么一个场景,每一次调用就加一呢?这样有没有办法拿到上一个对象的Minute值呢?
那就是我们要介绍的static关键字修饰成员变量(static int Minutes)可以做到: 称为静态成员变量,它不属于某个对象,而是属于整个类。这个变量可以通过类名作用域来改变,这个变量一旦改变,其他的对象也可以看到这个变量被改变
#include <iostream>
class Time{
public:
int a = 0;
//静态成员变量
static int Minute;
//静态成员函数
static void fun();
int func(){
std::cout << Minute << std::endl; //每个对象都可以直接访问静态成员变量
fun();//直接调用静态成员函数
}
};
//静态成员变量的初始化
int Time::Minute = 3;
//静态成员函数的初始化
void Time::fun(){
// std::cout << a << std::endl; //静态成员函数不能直接访问属于某个对象的a变量
std::cout << Minute << std::endl; //静态成员函数可以直接访问静态成员变量
}
int main()
{
Time time1;
time1.fun(); //对象调用静态成员函数
time1.Minute = time1.Minute + 100; //调用静态成员变量
Time time2;
time2.fun();
time2.func(); //调用普通成员函数
return 0;
}
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------static关键字的用法总结:
1)函数内部在定义一个局部变量时,在前面是用static关键字,则该变量就会保存到静态存储区,在编译的时候被初始化,如果不给初始化值,就会初始化成0,并且下次调用该函数的时候该变量保持上次离开该函数的值。
2)定义全局变量时前面使用static关键字,那么该全局变量只能在本文件中使用,无法在其他的文件被使用
3)在函数之前增加static,那么该函数只能在本源文件中调用,无法在其他源程序文件中调用。
4)在类中的变量或函数前边添加static关键字修饰的,都会变成静态成员函数或者变量,只初始化一遍,静态成员变量别的对象有改变这个值,所有的对象这个值都会被改变,静态成员可以直接使用"类名::变量名" 来访问,也可以用对象来访问。静态成员函数不能直接访问与某个对象相关的变量以及函数。上边的例子可以看以下