【关键字static】

前言

整理关键字static的作用以及在c语言和C++使用中的相同和区别

一、[C语言] static

1. static局部变量

在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变。

a、静态局部变量在函数内定义,生存期为整个程序运行期间,但作用域与自动变量相同,只能在定义该变量的函数内使用。退出该函数后, 尽管该变量还继续存在,但不能使用它。
b、对基本类型的静态局部变量若在说明时未赋以初值,则系统自动赋予0值。而对自动变量不赋初值,则其值是不定的。

void test1(void)
{
	int a = 0; //不初始化,编译器报错
	static int b; //默认初始化为0
	printf("a = %d; b = %d;\r\n", ++a, ++b);
}

void main()
{
	int cnt = 0;
	while (cnt != 5)
	{
		test1();
		++cnt;
	}
}
输出结果为:
			a = 1; b = 1;
			a = 1; b = 2;
			a = 1; b = 3;
			a = 1; b = 4;
			a = 1; b = 5;

2. static全局变量

在模块内(但在函数体外),一个被声明为静态的变量可以被模块(模块指cpp文件)内所用函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量。

全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。但是他们的作用域,非静态全局变量的作用域是整个源程序(多个源文件可以共同使用); 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件(.h或.cpp)内有效, 在同一源程序的其它源文件中不能使用它(注意,这一点和C++是不同的)。

#include <iostream.h>
void fn();
static int n; //定义静态全局变量
void main()
{
  n=20;
  cout<<n<<endl;
  fn();
}
void fn()
{
   n++;
  cout<<n<<endl;
}

3. static函数

在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用。那就是,这个函数被限制在声明它的模块的本地范围内使用。

这样定义的函数也成为静态函数:在函数的返回类型前加上关键字static,函数就被定义成为静态函数。定义静态函数的好处:
a、其他文件中可以定义相同名字的函数,不会发生冲突
b、静态函数不能被其他文件所用。它定义一个本地的函数。

#include <iostream.h>
static void fn();//声明静态函数
void main()
{
  fn();
}
void fn()//定义静态函数
{
  int n=10;
  cout<<n<<endl;
}

二、[C++] Static

1. static数据成员

C++中静态数据成员的特点有:
1、静态数据成员仅仅在初始化时不受访问权限的约束;
2、静态数据成员最好不要在.h文件中进行定义(初始化),而是放在.cpp文件中定义(初始化);
初始化格式: <数据类型><类名>::<静态数据成员名>=<值>
3、静态数据成员被类的所有对象所共享,包括类的派生类的所有对象;——即派生类和基类共享一个静态成员。
4、静态数据成员的类型可是所属类自己,即在一个类中可以声明该类自己的类型的静态成员对象,但是,不可以定义普通的成员对象,(指针可以)
5、在const成员函数中,可以修改static成员变量的值。普通成员变量的值,是不能修改的。

//file.h
#include <iostream.h>
class Myclass
{
public:
  Myclass(int a,int b,int c);
  void GetSum();
private:
  int a,b,c;
  static int Sum;//声明静态数据成员
};

//file.c
int Myclass::Sum=0;//定义并初始化静态数据成员
Myclass::Myclass(int a,int b,int c)
{
  this->a=a;
  this->b=b;
  this->c=c;
  Sum+=a+b+c;
}
void Myclass::GetSum()
{
  cout<<"Sum="<<Sum<<endl;
}

//main.c
void main()
{
  Myclass M(1,2,3);
  M.GetSum();
   Myclass N(4,5,6);
  N.GetSum();
  M.GetSum();
}

2. static成员函数

与静态数据成员一样,我们也可以创建一个静态成员函数,它为类的全部服务而不是为某一个类的具体对象服务。静态成员函数与静态数据成员一样,都是类的内部实现,属于类定义的一部分。

#include <iostream.h>
class Myclass
{
public:
  Myclass(int a,int b,int c);
  static void GetSum();/声明静态成员函数
private:
  int a,b,c;
   static int Sum;//声明静态数据成员
};
int Myclass::Sum=0;//定义并初始化静态数据成员
Myclass::Myclass(int a,int b,int c)
{
  this->a=a;
  this->b=b;
  this->c=c;
  Sum+=a+b+c; //非静态成员函数可以访问静态数据成员
}
void Myclass::GetSum() //静态成员函数的实现
{
  // cout<<a<<endl; //错误代码,a是非静态数据成员
  cout<<"Sum="<<Sum<<endl;
}
void main()
{
  Myclass M(1,2,3);
  M.GetSum();
  Myclass N(4,5,6);
  N.GetSum();
  Myclass::GetSum();
}

总结

1. 关于C语言static变量的理解:
a、若全局变量仅在单个C文件中访问,则可以将这个变量修改为静态全局变量,以降低模块间的耦合度;
b、若全局变量仅由单个函数访问,则可以将这个变量改为该函数的静态局部变量,以降低模块间的耦合度;
c、静态变量和全局变量放在程序的全局数据区,而不是在堆栈中分配,所以不可能导致堆栈溢出;
d、设计和使用访问动态全局变量、静态全局变量、静态局部变量的函数时,需要考虑重入问题(线程不安全);

2. 关于C++静态成员函数,可以总结为以下几点:
a、 出现在类体外的函数定义不能指定关键字static;
b、静态成员之间可以相互访问,包括静态成员函数访问静态数据成员和访问静态成员函数;
c、非静态成员函数可以任意地访问静态成员函数和静态数据成员;静态成员函数不能访问非静态成员函数和非静态数据成员;
d、由于没有this指针的额外开销,因此静态成员函数与类的全局函数相比速度上会有少许的增长;
e、调用静态成员函数,可以用成员访问操作符(.)和(->)为一个类的对象或指向类对象的指针调用静态成员函数,也可以直接使用如下格式:
<类名>::<静态成员函数名>(<参数表>)调用类的静态成员函数。

说明

参考链接:
https://blog.csdn.net/hemingliang1987/article/details/9428527
https://zhuanlan.zhihu.com/p/347930016
说明:以上部分内容摘抄于网络,文章只用于本人的学习记录,侵权必删!
致谢:在此感谢广大网友的分享!开源让世界更美好!
邮箱:helloworld0709@qq.com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值