C/C++ 中 static
关键字详解
static
是 C/C++ 中一个非常重要的关键字,用途灵活。它既可以修饰全局变量,也可以修饰局部变量和函数。在 C++ 中还可以修饰类成员变量和成员函数。本文将从不同角度详细讲解 static
的作用、生命周期和使用场景。
1. static
修饰全局变量
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| #include <stdio.h>
static int counter = 0;
void add() { counter++; printf("counter = %d\n", counter); }
int main() { add(); add(); add(); return 0; }
|
特点
- 生命周期:和普通全局变量一样,从程序开始到程序结束。
- 作用域:仅在当前源文件可见,无法通过
extern
在其他文件访问。
- 多次访问:变量值会一直保留,不会因为函数调用结束而销毁。
对比普通全局变量
特性 |
普通全局变量 |
static 全局变量 |
生命周期 |
整个程序运行期间 |
整个程序运行期间 |
作用域 |
跨文件可见 |
当前文件可见 |
初始化次数 |
程序启动时一次 |
程序启动时一次 |
多次访问效果 |
同一份存储空间,值累积 |
同一份存储空间,值累积 |
使用 static
修饰全局变量可以避免命名冲突,增强封装性。
2. static
修饰局部变量
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| #include <stdio.h>
void demo() { static int count = 0; count++; printf("count = %d\n", count); }
int main() { demo(); demo(); demo(); return 0; }
|
特点
- 生命周期:从程序开始到程序结束,与全局变量一样。
- 作用域:仅在定义的函数内部可见。
- 多次访问:每次调用函数时,变量不会重新初始化,保留上一次的值。
3. static
修饰函数
示例
1 2 3 4 5 6 7 8 9 10
| #include <stdio.h>
static void hello() { printf("Hello, static function!\n"); }
int main() { hello(); return 0; }
|
特点
- 作用域:仅在定义的源文件内部可见,无法在其他文件中调用。
- 用途:限制函数的访问范围,防止命名冲突。
4. C++ 中 static
的使用
4.1 类静态成员变量
- 作用:类共享的变量,不属于某个对象实例。
- 访问方式:通过类名或对象实例访问。
- 存储期:静态存储期。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| #include <iostream> using namespace std;
class MyClass { public: static int count; MyClass() { count++; } };
int MyClass::count = 0;
int main() { MyClass a; MyClass b; cout << "Count: " << MyClass::count << endl; return 0; }
|
4.2 类静态成员函数
- 作用:静态函数只能访问静态成员变量,不能访问非静态成员。
- 调用方式:通过类名或对象调用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| class MyClass { public: static void printCount() { cout << "Count: " << count << endl; } static int count; };
int MyClass::count = 0;
int main() { MyClass::count = 10; MyClass::printCount(); return 0; }
|
4.3 匿名命名空间替代 static
(C++ 特有)
在 C++ 中,static
修饰全局函数和变量可以被匿名命名空间替代:
1 2 3 4
| namespace { int counter = 0; void helper() {} }
|
匿名命名空间是 C++ 推荐的做法,比 static
更语义化。
5. 总结
使用场景 |
生命周期 |
作用域 |
特点 |
全局变量 static |
程序运行期 |
文件内部 |
限制文件可见性 |
局部变量 static |
程序运行期 |
函数内部 |
保留函数调用间的值 |
函数 static |
程序运行期 |
文件内部 |
文件内可见,不被其他文件引用 |
类静态成员变量 |
程序运行期 |
类作用域 |
所有对象共享 |
类静态成员函数 |
程序运行期 |
类作用域 |
仅能访问静态成员 |