1. 关于static
在C语言中,static
是一个非常重要的关键字,它可以修饰函数、变量以及代码块,用以实现不同的功能。下面分别介绍static修饰的三种情况。
1.1 static修饰变量
当static
修饰局部变量时,会使得该变量的生存期变得更加特殊。在函数内部定义的普通变量,它们的生命周期是在函数执行完毕后被销毁。但如果使用static
修饰该变量,那么它的生命周期将会被延长到整个程序的运行期间。
#include <stdio.h>
void func(){
static int num = 0;
printf("%d ", num);
num++;
}
int main(){
for (int i = 0; i < 5; i++){
func();
}
printf("\n");
return 0;
}
运行结果:
0 1 2 3 4
由此可见,使用static
修饰的num
变量,其值在不同的函数调用之间得到了保持。这也是static
修饰的变量被称为静态变量的原因。
1.2 static修饰函数
当static
修饰一个函数时,意味着该函数的可见性被限制在当前文件内。也就是说,在其他文件中无法通过函数名调用这个函数。
static void func(){
printf("This function is static.\n");
}
int main(){
func();
return 0;
}
运行结果:
This function is static.
在这个例子中,外部无法通过函数名func
来调用此函数。只有当前文件内的函数可以通过函数指针的形式来调用它。
1.3 static修饰代码块
当static
修饰代码块时,其作用是将该代码块声明为静态存储类。静态存储类变量和自动存储类变量的区别,就在于其生命周期是整个程序的执行期间。
#include <stdio.h>
void func(){
auto int num = 0;
static int s_num = 0;
printf("auto = %d, static = %d\n", num, s_num);
num++;
s_num++;
}
int main(){
for (int i = 0; i < 3; i++){
func();
}
return 0;
}
运行结果:
auto = 0, static = 0
auto = 0, static = 1
auto = 0, static = 2
可以看到,使用static
修饰的变量s_num
可以在函数调用之间保持其值。而使用auto
修饰的变量num
被重新初始化了。
2. static在内存管理中的应用
由于静态变量的特殊生命周期,使得它可以很好地应用于内存管理的相关场景。
2.1 用于计数
在某些情况下,需要在整个程序的执行期间维持一个计数器。比如在线程池中,需要记录当前空闲线程的数量。此时就可以使用static
变量来解决这个问题。
int getThread(){
static int id = 0;
return id++;
}
以上代码实现了一个简单的线程池的功能,每当调用getThread()
时,id的值会自增一次。
2.2 用于实现单例模式
单例模式的主要思想就是在整个程序的运行期间只维护一个实例对象。这可以通过static
变量来实现。
class Singleton{
public:
static Singleton& getInstance(){
static Singleton instance;
return instance;
}
private:
Singleton(){} // 禁止在其他地方生成实例
Singleton(const Singleton&); // 禁止复制实例
};
上面的代码中,getInstance()
是一个静态函数,用于返回全局唯一的Singleton实例。由于instance
被声明为static
,它的生命周期被限制在整个程序执行期间。
2.3 用于实现缓存
在程序运行期间,有些计算结果会重复出现。如果每次运算都重新计算一遍,势必会浪费大量时间和资源。在这种情况下,使用static
变量可以将重复计算的结果缓存起来,避免重复计算。
int fib(int n){
static int memo[100] = {0};
if (n <= 1){
return n;
}
if (memo[n] == 0){
memo[n] = fib(n-1) + fib(n-2);
}
return memo[n];
}
在这个例子中,memo
是一个静态数组,用于存放fib()函数的计算结果。如果某一项还没有被计算过,则进行正常的计算,同时将结果存入memo
中。如果某一项已经被计算过,则直接读取memo
中的结果。
3. 总结
static
在C语言中具有多种使用方式。在变量和函数中的应用,使得程序的执行更加灵活,可以更好地满足实际需求。在内存管理中的应用,使得程序的运行更加高效,减少了资源的浪费。在实际开发中,充分利用static
的特性可以将代码写得更加简洁优雅。