整理关键字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
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
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
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
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<
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
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)