(1)隐藏
这个作用要有多个源文件才能看到:
头文件aa.h
void fun();
源文件aa.c
#include<stdio.h>
#include"aa.h"
//变量未加static
int A = 666;
//函数未加static
void fun()
{
printf("this function is in \"a.h\"\n");
}
源文件main.c
#include<stdlib.h>
#include<stdio.h>
#include"aa.h"
int main()
{
//全局声明,不声明A就“看不到”了
extern int A;
printf("%d\n",A);
fun();
system("pause");
return 0;
}
这一切都很好,如果加了static,也就是aa.c里的int A;变成static int A;那么A变量就无法在别的源文件中看到了。同理 在aa.c源文件里void fun()前面加static,那么除了aa.c源文件,其他任何原件都不可以看到fun();这就是static的隐藏功能;
利用这一特性可以在不同的文件中定义同名函数和同名变量,而不必担心命名冲突。
(2)改变变量的生命周期 (这里只有变量)
静态存储区:只有全局变量和静态变量存在这里;他们两个的生命周期是一样的(相对于局部变量),从程序开始到结束。不过静态变量有一个特点,它只初始化一次,换句话说,初始化静态变量的代码在第一次执行后,就不在执行了。
#include<stdlib.h>
#include<stdio.h>
#include"aa.h"
int foo()
{
static int x = 6;
return x--;
}
int main()
{
/*
extern int A;
printf("%d\n",A);
fun();
*/
int i;
for (i = 0; i < 6; ++i)
printf("%d\t\t%d\n",i+1,foo());
system("pause");
return 0;
}
结果 1 6
2 5
3 4
4 3
5 2
6 1
已经很清楚了
(3) static变量(不论全局还是局部)默认初始为0
存储在静态存储区的变量都有这个特性,这样子的好处是可以简化程序员对变量的初始化。
static int m;
static int n[5][5];
static char ch[5];
printf("m=%d \n",m);
int i, j;
for (i = 0; i < 5; ++i)
for (j = 0; j < 5; ++j)
printf("%d",n[i][j]);
printf("\n(start)%s(end)\n",ch);
结果 m=0
0000000000000000000000000
(start)(end)
画个内存图看一下静态存储区在哪里:
(4)c++中的static用法(在c的基础上进行扩展,主要是在类内的用法)
①静态成员变量:在类内只是声明:class{pribvate:static int a;//只是声明}
-静态数据成员存储在静态存储区。静态数据成员定义时要分配空间,所以不能在类声明中定义。只能在类外定义;
定义时要加上类的域解析运算符,因为它只属于一个类,即使这个类有许多对象,这些对象与静态成员变量的关系是共享的,即使类没有实例,我们仍可操作它;
-static成员变量的初始话是在类外,此时不能再带上static的关键字。
private,protected 的static成员最然可以在类外初始化,但是不能在类外被访问。
-类的静态数据成员有两种访问形式:
<类对象名>.<静态数据成员名> 或 <类类型名>::<静态数据成员名>
如果静态数据成员的访问权限允许的话(即public的成员),可在程序中,按上述格式来引用静态数据成员
-静态成员变量比全局变量的优势:信息隐藏,以及不产生命名突;
②静态成员函数:属于类,不属于任何一个实例对象。没有this,不能访问普通成员变量,无法调用非静态函数 ;
-类内声明,类外定义,加域解析运算符;
-静态成员函数可以访问静态成员变量
class class_A{
private:
static int A;
public:
class_A()
{
//证明静态成员变量的初始化是
比较早的
cout << "在构造之前输出A的值" << A << endl;
A = 5;
printf("构造函数初始化A为5\n");
}
static void B();
void C() {
A = 8;
cout << A << endl;
cout << "成员函数C()的改变A为8" << endl;
}
};
int class_A::A = 7;//这里必须先定义才能使用
void class_A::B() {
cout << A << endl;
cout << "静态成员函数输出A" << endl;
}
int main()
{
class_A a;
a.C();//成员函数可以使用静态变量
a.B();//对象可以引用静态成员函数
class_A::B();//静态成员函数可以用类名::使用
return 0;
}