c/c++中static的用法

概述

static:
作为c/c++的关键字之一,具有多种含义和应用,static 关键字可用于声明变量、函数、类数据成员和类函数。默认情况下,在所有块的外部定义的对象或变量具有静态持续时间和外部链接。 静态持续时间意味着,在程序启动时分配对象或变量,并在程序结束时释放对象或变量。 外部链接意味着,变量的名称在用于声明变量的文件的外部是可见的。 相反,内部链接意味着,名称在用于声明变量的文件的外部是不可见的。

在以下情况下,可使用 static 关键字:

  1. 在文件范围(全局和/或命名空间范围)内声明变量或函数时,static 关键字将指定变量或函数具有内部链接。 在声明变量时,变量具有静态持续时间,并且除非您指定另一个值,否则编译器会将变量初始化为 0。

  2. 在函数中声明变量时,static 关键字将指定变量将在对该函数的调用中保持其状态。

  3. 在类声明中声明数据成员时,static 关键字将指定类的所有实例共享该成员的一个副本。 必须在文件范围内定义静态数据成员。 声明为 const static 的整型数据成员可以有初始值设定项。

  4. 在类声明中声明成员函数时,static 关键字将指定类的所有实例共享该函数。 由于函数没有隐式 this 指针,因此静态成员函数不能访问实例成员。 若要访问实例成员,请使用作为实例指针或引用的参数来声明函数。

  5. 不能将联合成员声明为静态的。 但是,全局声明的匿名联合必须是显式声明的 static。

静态全局变量

全局变量:
在函数外部定义的变量。它不属于哪一个函数,它属于一个源程序文件。其作用域是整个源程序。在函数中使用全局变量,应该做全局变量说明。只有在函数内经过说明的全局变量才能使用。但在一个函数之前定义的全局变量,在该函数内使用可以不再加以说明。
静态全局变量:
定义在函数体外,用来修饰全局变量,未经初始化的静态全局变量会被自动初始化为0;在申明静态全局变量的文件以外是不可见的。不同的源文件中都可以使用同一个全局变量,但当定义为静态全局变量之后,其作用域知存在于当前源文件。

举例:
变量maxstatic.cpp中定义为静态全局变量,因此无法在main.cpp中使用,运行会提示 “无法解析的外部符号”

//main.cpp
#include 
#include "static.h"
using namespace std;

int a = 5; //全局变量

int main()
{
	extern int max; //申明静态全局变量,运行失败,想用max,则max需定义为全局变量,而不是静态全局变量
	
	cout << "max: " << max << endl;

	fun();

	return 0;
}
//static.pp
#include 
#include  "static.h"
using namespace std;

static int max = 1000000; //静态全局变量,要想在main.cpp中使用,需定义为全局变量
//int max = 1000000; 
 void fun(void)
 {
	 int min = 11;
	 cout << "min:" << min << endl;

 }
//static.h
#include 

void fun(void);

运行结果: 无法编译成功
c/c++中static的用法_第1张图片
想使用static.cpp中的全局变量max,则需要定义为全局变量,而不是静态全局变量。
c/c++中static的用法_第2张图片

静态局部变量

局部变量:
在程序中只在特定过程和函数中可以访问的变量,是相对于全局变量而言的。在C等面向过程语言中,局部变量可以和全局变量重名,但是局部变量会覆盖全局变量。在函数内引用这个变量时,会用到同名的局部变量,而不会用到全局变量。
静态局部变量:
定义在函数体内的变量加上static修饰符,它的存在意义是随着第一次函数的调用而初始化,但却不随着函数的调用结束而销毁。因此静态局部变量保存在全局数据区,而不是保存在栈中,每次的值保持到下一次调用,直到下次赋新值。

举例:

#include 
using namespace std;
void test(void)
{
	int a = 10; // 局部变量
	static int b = 10; //静态局部变量

	a++;
	b++;
	cout << "a:" << a << ", b: " << b << endl;
}
int main()
{
	test();
	test();
	test();
	test();
	test();
	test();

	return 0;
}

运行结果,可以看到局部变量和静态局部变量的差异。
c/c++中static的用法_第3张图片

静态函数

函数:
c/c++函数是c/c++程序的基本组成单位,用于实现特定的功能或计算。

静态函数:
在函数定义前加上修饰符static,作用和静态全局变量类似;函数的定义和生命在默认状态下都是extern的,但静态函数只是在申明他的文件当中可见,不能被其余文件所用。
举例:

//main.cpp
#include 
#include "static.h"

using namespace std;


int main()
{
	fun();
	test();//报错,无法调用static.cpp中的静态函数

	return 0;
}
//static.cpp
#include 
#include  "static.h"
using namespace std;

//普通函数
 void fun(void)
 {
	 int min = 11;

	 cout << "min:" << min << endl;

 }

 //静态函数,无法在其他文件中使用该函数
 static void test(void)
 {
	 int min = 1111;
	 cout << "min:" << min << endl;

 }
//static.h
#include 

void fun(void);

static void test(void);

运行结果:可以看到,在main函数中调用test()函数,会提示声明未定义。
c/c++中static的用法_第4张图片

类的静态成员和静态成员函数

类的静态成员:
修饰class的数据成员,这种数据成员的生存期大于class的对象;静态数据成员是每个class有一份,普通数据成员是每个实例有一份,因此静态数据成员也叫类变量,普通数据成员也叫实例变量。

类的静态成员函数:
在成员函数前加上static就变成了静态成员函数;静态成员函数不能访问非静态成员函数或数据成员,但非静态可以访问静态。
因为静态是属于类的,无法感知创建的对象,所以它对你对象的函数或者数据是一无所知的,所以它没办法调用;而反过来,创建的对象是对类是可以感知的,所以是可以调用类函数和类成员的。
静态成员函数能够继承和覆盖,但没法是虚函数。

#include 
using namespace std;

class A
{
public:
	static int a; //类的静态成员变量
	static int get_a();//类的静态成员函数

	int b;
	int get_b();
};
int A::a = 100; //静态成员变量可以在类的外部直接定义
//int A::b = 1000; //普通成员变量在类的外部定义失败

int A::get_a()
{
	return a; //类的静态成员函数只能访问类的静态成员变量
	//return b + a; //静态成员函数无法调用普通成员变量
}
int A::get_b()
{
	return b + a;//普通成员函数可以调用静态成员变量
}

int  main(void)
{
	cout << "a: " << A::get_a() << endl; //不需要类的实例,也可以调用类的静态成员函数

	A m;
	m.b = 90;
	m.a = 100000;

	cout << m.get_a() << endl;
	cout << m.get_b() << endl;
	cout << m.a << endl;

	return 0;

}

运行结果:
c/c++中static的用法_第5张图片

你可能感兴趣的:(C/C++,c语言,c++,static)