C语言中:
静态变量作用范围在一个文件内,程序开始时分配空间,结束时释放空间,默认初始化为0,使用时可以改变其值。
静态变量或静态函数只有本文件内的代码才能访问它,它的名字在其它文件中不可见。
用法1:函数内部声明的static变量,只在本函数内有效,函数只分配一次内存,不初始化,其值为0,函数返回时,该变量不会消失!
用法2:函数外部申明的static变量,只在本文件内有效,如果不初始化,则为0.
用法3:将函数申明为static,则该函数也只能在本文件使用!
进一步详细解释如下:
1.先来介绍它的第一条也是最重要的一条:隐藏
当我们同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性。为理解这句话,我举例来说明。我们要同时编译两个源文件,一个是a.c,另一个是main.c. 下面是a.c的内容:
static int i = 10; // global variable
void msg()
{
printf("i = %d\n", i++);
}
下面是main.c的内容:
extern int i; //extern ariable must be declared before use
int main(void)
{
printf("%d ", i);
msg();
return 0;
}
程序的运行结果是:
编译通过,运行出现错误,原因就是static变量只能在在本文件中使用,若改动将a.c文件中的static去掉,或去掉main.c中的extern,这样两个问津中的i也是不同的两个变量!
验证static变量的生命周期:
int fun(int a)
{
static int i;
i += a;
printf("%d\n", i);
}
int main()
{
int a = 10;
fun(a);
fun(a);
fun(a);
return 0;
}
可知运行结果为20 30 40;若去掉static 则结果为20 20 20
2. static的第二个作用是保持变量内容的持久
3. static的第三个作用是默认初始化为0.其实全局变量也具备这一属性,因为全局变量也存储在静态数据区
最后对static的三条作用做一句话总结。首先static的最主要功能是隐藏,其次因为static变量存放在静态存储区,所以它具备持久性和默认值0.
4. 用static声明的函数和变量小结
static 声明的变量在C语言中有两方面的特征:
1)、变量会被放在程序的全局存储区中,这样可以在下一次调用的时候还可以保持原来的赋值。这一点是它与堆栈变量和堆变量的区别。
2)、变量用static告知编译器,自己仅仅在变量的作用范围内可见。这一点是它与全局变量的区别。
Tips:
A.若全局变量仅在单个C文件中访问,则可以将这个变量修改为静态全局变量,以降低模块间的耦合度;
B.若全局变量仅由单个函数访问,则可以将这个变量改为该函数的静态局部变量,以降低模块间的耦合度;
C.设计和使用访问动态全局变量、静态全局变量、静态局部变量的函数时,需要考虑重入问题;
D.如果我们需要一个可重入的函数,那么,我们一定要避免函数中使用static变量(这样的函数被称为:带“内部存储器”功能的的函数)
E.函数中必须要使用static变量情况:比如当某函数的返回值为指针类型时,则必须是static的局部变量的地址作为返回值,若为auto类型,则返回为错指针。
从以上分析可以看出, 把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域, 限制了它的使用范围。
(1) static 函数与普通函数作用域不同。仅在本文件。只在当前源文件中使用的函数应该说明为内部函数(static),内部函数应该在当前源文件中说明和定义。对于可在当前源文件以外使用的函数,应该在一个头文件中说明,要使用这些函数的源文件要包含这个头文件
(2) static全局变量与普通的全局变量有什么区别:static全局变量只初始化一次,防止在其他文件单元中被引用;
(3) static局部变量和普通局部变量有什么区别:static局部变量只被初始化一次,下一次依据上一次结果值;
(4) static函数与普通函数有什么区别:static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝.
(5) 全局变量和静态变量如果没有手工初始化,则由编译器初始化为0。局部变量的值不可知。
5. C++的static
静态成员函数的特点是:不管这个类创建了多少个对象,其静态对象在内存中之保留一份拷贝,这个拷贝为该类的所有对象共享。
1.静态数据成员
类的普通成员在类的每一个对象中都有一个拷贝,静态数据成员是类的一种特例采用static修饰,属于类属性,每一个只有一个拷贝,由该类的所有对象共同维护和使用,从而实现了同类的不同对象之间的数据共享
静态数据成员的定义分为两个必不可少的部分:类内申明,类外初始化
申明:static 数据类型 静态数据成员名;
初始化:数据类性 类名::静态数据成员名=初始化;
注意事项:
a.静态数据成员脱离具体对象而独立存在,其存储空间是独立分配的,不是任何对象对象存储空间的一部分
b.静态数据成员在程序开始时产生,在程序结束时消失,具有静态生存期
c.在类外对静态数据成员初始化,必须使用类作用域运算符::限定它所属类
访问静态数据成员:
a.与普通成员变量一样,可以通过对象,对象指针,对象引用来访问
b.类名::静态成岩变量
2.静态成员函数
静态数据成员为类属性,在定义类后,建立对象前就存在。因此建立对象前不能通过成员函数存取静态数据成员。C++提供了静态成员函数,它用来存取类的静态成员,它属于整个类而不属于类中的某个对象,是该类的所有对象共享的成员函数。
静态成员函数可以在类内定义,也可以在类内申明为static,在类外定义,此时不用加static
普通的成员函数一般都隐含了一个 this 指针,this 指针指向类的对象本身,