CC++中static关键字的⽤法
(⼀)变量的分类
变量可以分为全局变量、静态全局变量、静态局部变量和局部变量这四种。这⼏种变量的特点如下:
(1) 按存储区域分,全局变量、静态全局变量和静态局部变量都存放在内存的静态存储区域,局部变量存放在内存的栈区。
(2) 按作⽤域
1.全局变量在整个⼯程⽂件内都有效;
const的作用2.静态全局变量只在定义它的⽂件内有效;
3.静态局部变量只在定义它的函数内有效,只是程序仅分配⼀次内存,函数返回后,该变量不会消失;
4.局部变量在定义它的函数内有效,但是函数返回后失效。
(3)三者之间的区别
1.当⼀个源程序由多个源⽂件组成时,⾮静态的全局变量在各个源⽂件中都是有效的。
2.静态全局变量限制了其作⽤域,只在定义该变量的源⽂件内有效,在同⼀源程序的其它源⽂件中不能使⽤它。由于这种限制性,只能为该源⽂件内的函数公⽤,因此可以避免在其它源⽂件中引起错误。
3.把局部变量改变为静态变量后是改变了它的存储⽅式即改变了它的⽣存期,把全局变量改变为静态变量后是改变了它的作⽤域,限制了它的使⽤范围。
4.static 函数与普通函数作⽤域不同。仅在本⽂件。只在当前源⽂件中使⽤的函数应该说明为内部函数(static),内部函数应该在当前源⽂件中说明和定义。对于可在当前源⽂件以外使⽤的函数,应该在⼀个头⽂件中说明,要使⽤这些函数的源⽂件要包含这个头⽂件
5.static全局变量只初始化⼀次,防⽌在其他⽂件单元中被引⽤;
6.static局部变量只被初始化⼀次,下⼀次依据上⼀次结果值;
7.static函数在内存中只有⼀份,普通函数在每个被调⽤中维持⼀份拷贝.
8.全局变量和静态变量如果没有⼿⼯初始化,则由编译器初始化为0。局部变量的值不可知。
(⼆)C中的static关键字
1.静态全局变量
在全局变量之前加上关键字static,该变量就变为了静态全局变量;
特点:该变量在全局数据区分配内存,存储于内存中的静态存储区域;
如果不显⽰初始化,那么变量会被隐式初始化为0;
静态全局变量只在本源⽂件可见,从定义之处开始到本⽂件结束;不能被同⼀⼯程下的其他⽂件通过extern调⽤
代码
//test.c
int main
{
static n = 10;
fun(n);
}
//main.c
extern int n ;
int main()
{
cout<<n<<endl;
}
main.c不到int n 的定义点。
2.静态局部变量
在局部变量前加上static关键字,该变量就变为了静态局部变量;
特点
该变量在全局数据区分配内存,存储于内存中的静态存储区域;
如果不显⽰初始化,那么变量会被隐式初始化为0;
静态全局变量始终驻留在全局数据区,直到程序运⾏结束;但它的作⽤域为局部作⽤域; 当定义此变量的函数或语句块结束时,其作⽤域也随之消失
代码
#include <stdio.h>
#include <stdlib.h>
void fun()
{
static int var1 = 0; //静态局部变量
int var2 = 0; //⾃动变量
var1 ++;//1
var2 ++;//1
printf("var1 = %d ", var1);
printf("var2 = %d\n", var2);
}
int main()
{
int i = 0 ;
for( ; i < 4 ;++i)
{
printf("i = %d\n",i);
fun();
}
return 0;
}
执⾏结果如下图:
3.静态函数
在函数的返回类型之前加上static关键字,函数就被定义为静态函数;
特点
静态函数只能本源⽂件可见;
在⽂件作⽤域下声明的inline函数被默认为static类型;
(⼆)C++中的static关键字
1.静态数据成员
(1)类中的数据成员的声明前加上static关键字,该数据就成了该类的静态数据成员并且只能被定义⼀次;需要将此静态数据成员定义在类定义之外
(2)静态数据成员被类的所有对象所共享,包括类的派⽣类的对象;
(3)类的各个对象都拥有类的每⼀个普通数据成员的副本,但是静态数据成员只有⼀个实例存在,与定义了多少类对象⽆关;
(4)静态数据成员也遵守public/protected/private访问规则;
(5)静态数据成员的作⽤之⼀是统计有多少个对象实际存在;
(6)静态数据成员属于类中的全局变量,与程序中的同名全局变量不冲突
不能在类中初始化,不能在类的构造函数中初始化成员,否则每创建类的⼀个对象静态数据成员都要被重新初始化⼀次;
不能在类体内进⾏赋值,由于它被所有该类的对象共享;当在⼀个对象⾥对静态数据成员进⾏赋值时,其他对象⾥的内容也会发⽣变化;
为了避免发⽣赋值混乱,不可再类体内进⾏初始化;
(7)静态数据成员的值对所有对象是⼀样的,可以被初始化,但只能在类外初始化;
初始化形式: 数据类型名 类作⽤域::静态数据成员 = 初值
(8)const静态数据成员可以在类定义内初始化,但还是需要定义在类定义之外,但是不进⾏赋值
class A
{
private:
static const int size = 10;
}
const int A::size;
(9)静态数据成员可以作为类内成员函数的默认值存在,⽽普通数据成员不可以,
代码如下:
#include <iostream>
using namespace std;
class A
{
public:
A(int n = 0):c(n)
{
cout<<"A()"<<endl;
cout<<"A::a = "<<a<<endl;
}
~A()
{
cout<<"~A()"<<endl;
}
static int a ;
private:
int c ;
};
int A::a = 1;//静态数据成员初始化
class B:public A
{
public:
B(int n = 0):b(n)
{
cout<<"B::b = "<<b<<endl;
}
~
B()
{
cout<<"~B()"<<endl;
}
private:
int b ;
};
int main()
{
A x(2);
B y(3);
y.a = 10;
cout<<x.a<<endl;//10 由于b可以访问基类A的静态数据成员,属于全局变量
return 0;
}
2.静态成员函数
特点:
(1)静态成员函数不属于任何⼀个对象,没有隐含的指向对象的this指针;
当调⽤⼀个对象的成员函数(⾮静态)时,系统会把该对象的地址赋给成员函数的this指针;⽽静态成员函数⽆this指针, 没有指向某个对象,就⽆法对⼀个对象中的⾮静态成员进⾏默认访问(在引⽤数据成员时不指定对象名)
静态成员函数的地址可以被普通指针存储,⽽普通成员函数的地址需要⽤类成员函数指针存储;
代码⽰例:
class base
{
static int func1();
int func2();
};
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论