static关键字作用
隐藏:
同时编译多个文件时,所有未加static的全局变量和函数都具有全局可见性
static修饰全局变量/函数时,作用是改变其作用域,使其只能在模块内使用
全局静态变量和局部静态变量作用域区别:
全局:从定义之处开始,到文件结尾
局部:局部作用域,当定义它的函数结束时作用域结束,没有销毁,仍在内存中,只是不能访问,再次调用时,保持上次的值不变,只初始化一次。
//举例说明:同时编译两个源文件a.c和main.c,a和msg未加static修饰,全局可见性,所以可以在main.c中使用
//加上static对其他文件隐藏:利用这一特性可以在不同的文件中定义同名函数和变量,不用担心命名冲突
//对于函数来讲,static的作用仅限于隐藏
//a.c
char a = 'A'; // global variable
void msg()
{
printf("Hello\n");
}
//main.c
int main()
{
extern char a; // extern variable must be declared before use
printf("%c ", a);
(void)msg();
return 0;
}
// 程序的运行结果是:
// A Hello
存储在静态存储区(只有全局变量和static变量):
生存期为整个源程序
#include <stdio.h>
int fun(){
static int count = 10; //在第一次进入这个函数的时候,变量a被初始化为10!并接着自减1,以后每次进入该函数,a
return count--; //就不会被再次初始化了,仅进行自减1的操作;在static发明前,要达到同样的功能,则只能使用全局变量:
}
int count = 1; // 全局变量
int main(void)
{
printf("global\t\tlocal static\n");
for(; count <= 10; ++count)
printf("%d\t\t%d\n", count, fun());
return 0;
}
// 输出结果:
// 1 10
// 2 9
// 3 8
// 4 7
// 5 6
// 6 5
// 7 4
// 8 3
// 9 2
// 10 1
默认初始化为0:
在静态数据区,内存中所有的字节默认值都是0x00
#include <stdio.h>
int a; //global
int main()
{
int i;//local
static char str[10];
printf("global integer: %d\n", a);
printf("loacl integer: %d\n", i);
return 0;
}
// global integer: 0
// loacl integer: 341742034
C++中的类成员声明static:
- 类的静态成员函数是属于整个类而非类的对象,所以它没有this指针。这就导致了它仅能访问类的静态数据和静态成员函数
参见this指针。因为this指针是指向类某一个对象的指针,并非整个类。非静态数据都是属于类对象的,需要通过this访问
静态成员函数属于整个类,在类实例化对象之前就已经分配空间。而类的非静态成员在类实例化对象后才有内存空间,所以静态成员函数不能调用非静态,就好比没有声明一个变量确使用它。
- 不能将静态成员函数定义为虚函数。
不能被重写,虚函数是可以被重写的,静态函数是类属的
总结:
存储在静态存储区。
【非类成员】
static修饰全局函数:改变作用域,使其只能在模块内使用
static修饰全局变量:改变作用域,使其只能在模块内使用
static修饰局部变量:改变其生命周期,当定义它的函数结束时没有销毁,仍在内存中;再次调用时保持上次的值不变,只初始化一次。
【类成员】
static修饰成员函数:
1.属于类,不属于对象。没有this指针,所以仅能访问类的静态数据和静态成员函数。
2.非静态成员函数可以任意访问静态成员函数和静态数据成员;
static修饰成员变量:
1.静态数据成员只分配一次内存,供所有对象共用。所以,静态数据成员的值对每个对象都是一样的,可以改变。
2.在类中不能对static数据成员进行初始化,要初始化的话必须在类外进行定义!并且去掉static关键字
3.const int 类型的static成员便可以在类定义体内部进行初始化。记住,一定只能是const int型的,换成const string ,double都不行的。
static const int age = 20;//在类的定义体内进行初始化