由于容易忘记static
关键字的用法,每次搜索还得筛选一下才能得到想要的结果。故写下此文章记录。
一、C
C
语言中,static
可以用来修饰全局变量、局部变量和函数。
1.1 C
:static
修饰的全局变量
在C
语言中,当一个全局变量被static
修饰后,其特征:
- 在全局数据区分配内存(这点没变化)
- 仅在声明的时候初始化,如果未初始化,默认赋值为0
- 作用域为本文件内,从定义开始到文件末尾(可见性)
1.2 C
:static
修饰的局部变量
- 在全局数据区分配内存(原本在栈区)
- 仅能被初始化一次
- 作用域为本函数中,从定义处到该函数的末尾
来做几个小实验。
例1. 验证局部变量初始化行为
/* * main.c */ #include <stdio.h> static int g_int_uninit; static int g_int = 1023; void foo(int num) { static int l_int_uninit; printf("static local uninit var = %d\n", l_int_uninit); static int l_int = 1; // 调用了五次,实际上只生效了一次(**第一次被调用时**) l_int += num; printf("after foo(), static local var = %d\n", l_int); } int main() { printf("global static uninit int = %d\n", g_int_uninit); printf("global static int = %d\n", g_int); for (int i = 0; i < 5; ++i) foo(5); return 0; }
在例1的基础上,稍作小改动,声明引入了一个定义在其他文件的变量(定义在test.h中,是一个全局静态变量)。编译没问题,但是链接提示找不到符号。证明作用域确实被修改了。
1.3 C
:static
修饰的函数
- 修改“可见性”,仅在当前文件生效。
这点和修饰变量时相似,注意这里的“可见性”用引号圈起来了。C
语言里面,定义在一个文件里的函数,默认是全局可见的。而static
关键字能够改变这一性质,使其仅能在当前文件中可见(可被调用)。(这个有待求证,用GCC 8.3.0实际测试是可以访问的)二、
C++
C++
中,static
关键字的作用与C
中大同小异。
相较于C
,C++
多了对象的概念,因此会有些更多用法。2.1
C++
:static
修饰成员函数 - 该成员函数不与类实体绑定,即能在不实例化类对象的情况下被调用。
三、用途
3.1 单例模式的实现
C++
单例设计模式的实现方法之一,借助了静态局部变量初始化以后不会再初始化的特点。(线程安全在C++11
(含)标准以后支持)
class Singleton { public: static Singleton* GetInstance() { static Singleton* s = new Singleton(); // C++11以后是线程安全的 return s; } private: Singleton(); ~Singleton(); };
3.2 改变生命周期/仅初始化一次
略。
四、总结