静态变量作用范围在一个文件内,程序开始时分配空间,结束时释放空间,默认初始化为0,使用时可以改变他的值。且静态变量或静态函数只有本文件内的代码可以访问他,他的名字在其他文件中不可见。
1)、变量会被放在程序的静态区中,这样可以在下一次调用的时候还可以保持原来的赋值。这一点是它与堆栈变量和堆变量的区别。
2)、变量用static告知编译器,自己仅仅在变量的作用范围内可见。这一点是它与全局变量的区别。
static的作用
- 隐藏:static函数,static变量均可
当同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性。
举例来说明。同时编译两个源文件,一个是a.c,另一个是main.c
a.c中定义的全局变量和函数都可以在main.c中使用,因为所有未加static前缀的全局变量和函数都具有全局可见性,其它的源文件也能访问。如果加了static,就会对其它源文件隐藏。利用这一特性可以在不同的文件中定义同名函数和同名变量,而不必担心命名冲突。
- 函数之间的通信机制:static变量
如果一局部变量被声明为static,那么将只有唯一的一个静态分配的对象,它被用于在该函数的所有调用中表示这个变量。这个对象将只在执行线程第一次到达它的定义使初始化。
- 局部静态对象
对于局部静态对象,构造函数是在控制线程第一次通过该对象的定义时调用。在程序结束时,局部静态对象的析构函数将按照他们被构造的相反顺序逐一调用,没有规定确切时间。
- 静态成员和静态成员函数
如果一个变量是类的一部分,但却不是该类的各个对象的一部分,它就被成为是一个static静态成员。一个static成员只有唯一的一份副本,而不像常规的非static成员那样在每个对象里各有一份副本。同理,一个需要访问类成员,而不需要针对特定对象去调用的函数,也被称为一个static成员函数。类的静态成员函数只能访问类的静态成员(变量或函数)。如果想要在外部调用类的静态成员或者静态函数,需要使用类名::的形式
- 保持变量内容的持久
存储在静态数据区的变量会在程序刚开始运行时就完成初始化,也是唯一的一次初始化。也就是说,如果在某个函数中定义静态变量,在执行程序期间反复调用这个函数,只会对静态变量初始化一次,不会反复进行赋值。
实例:
在编程语言C和C++中,static
关键字有多种用途,具体行为取决于它的使用上下文。
- 在函数内部:当
static
关键字用于函数内部的变量时,它会使变量的值在函数调用之间持久化。这种变量又被称作“静态局部变量”。与普通局部变量不同,静态局部变量在程序执行到声明它的那一部分时初始化,通常是在程序开始运行时(而不是每次进入函数时)。即使函数调用结束,它的值也不会消失,下次再进入该函数时,变量将保持上次存储的值。
例如:
void function() {
static int counter = 0;
counter++;
printf("%d ", counter);
}
// 调用function()会看到counter的值每次递增,并保持在调用之间。
- 在函数外部:当
static
用于文件范围内的全局变量或者函数时,它将使得该变量或者函数的作用域限定在声明它的文件内。这就意味着这个变量或者函数不能被其他文件使用,即使使用extern
关键字也不可以。这是控制程序模块间耦合、隐藏内部实现的一种方式。
例如:
// 在 some_module.c文件中
static int internal_variable = 0; // 仅在some_module.c中可见
static void internal_function() { /* ... */ } // 仅在some_module.c中可见
// 这些静态声明的符号在other_module.c中是不可访问的。
- 在类中:在C++中,当
static
用于类的成员时,它表明这是一个属于类的,而不是属于类的某个特定对象的成员。静态成员变量在内存中只有一份副本,无论创建了多少对象。静态成员函数也类似,它不能访问类的非静态成员变量和成员函数。
例如:
class Example {
static int static_value; // 静态成员变量
int non_static_value; // 非静态成员变量
static void static_function() {
// 可以访问static_value,但不能访问non_static_value
}
};
// 静态成员必须在类外部定义
int Example::static_value = 0;
总结来说,static
关键字提供了一种控制变量和函数存储期(lifetime)和可见性(visibility)的方式,能够帮助开发者创建更加维护性和封装性更好的代码。