一、静态局部变量
1、基本介绍
-
当 static 关键字用于修饰函数内部的局部变量时,该变量的生命周期会延长到整个程序运行期间
-
静态局部变量只会初始化一次,即使函数多次调用,它的值也会保留上次调用结束时的值
-
静态局部变量的作用域仍然仅限于该函数内
2、演示
- 静态局部变量只会初始化一次
#include <stdio.h>
void counter() {
static int count = 0;
count++;
printf("count: %d\n", count);
}
int main() {
counter();
counter();
counter();
return 0;
}
# 输出结果
count: 1
count: 2
count: 3
- 静态局部变量的作用域仅限于函数内
#include <stdio.h>
void counter() {
static int count = 0;
count++;
printf("counter - count: %d\n", count);
}
int main() {
counter();
printf("main - count: %d\n", count);
return 0;
}
# 输出结果
错误 C2065 “count”: 未声明的标识符
错误(活动) E0020 未定义标识符 "count"
二、静态全局变量或函数
1、基本介绍
- 当 static 关键字用于修饰全局变量或函数时,它会将变量或函数的作用域限制在当前源文件内,其他文件无法通过 extern 访问
2、演示
- staticTestFile.c
#include <stdio.h>
int normal_var = 100;
static int hidden_var = 10;
void normal_print() {
printf("normal_print");
}
static void hidden_print() {
printf("hidden_print");
}
(1)对于静态全局变量
- 直接访问
normal_var
#include <stdio.h>
int main() {
printf("normal_var = %d\n", normal_var);
return 0;
}
# 输出结果
错误 C2065 “normal_var”: 未声明的标识符
错误(活动) E0020 未定义标识符 "normal_var"
- extern 声明访问
normal_var
#include <stdio.h>
extern int normal_var;
int main() {
printf("normal_var = %d\n", normal_var);
return 0;
}
# 输出结果
normal_var = 100
- 直接访问
hidden_var
#include <stdio.h>
int main() {
printf("hidden_var = %d\n", hidden_var);
return 0;
}
- extern 声明访问
hidden_var
# 输出结果
错误 C2065 “hidden_var”: 未声明的标识符
错误(活动) E0020 未定义标识符 "hidden_var"
#include <stdio.h>
extern int hidden_var;
int main() {
printf("hidden_var = %d\n", hidden_var);
return 0;
}
# 输出结果
错误 LNK1120 1 个无法解析的外部命令
错误 LNK2001 无法解析的外部符号 hidden_var
(2)对于静态全局函数
- 直接访问
normal_print
int main() {
normal_print();
return 0;
}
# 输出结果
normal_print
- extern 声明访问
normal_print
extern void normal_print();
int main() {
normal_print();
return 0;
}
# 输出结果
normal_print
- 直接访问
hidden_print
int main() {
hidden_print();
return 0;
}
# 输出结果
错误 LNK1120 1 个无法解析的外部命令
警告 C4013 “hidden_print”未定义;假设外部返回 int
错误 LNK2019 无法解析的外部符号 hidden_print,函数 main 中引用了该符号
- extern 声明访问
hidden_print
extern void hidden_print();
int main() {
hidden_print();
return 0;
}
# 输出结果
错误 LNK1120 1 个无法解析的外部命令 otherTest
错误 LNK2019 无法解析的外部符号 hidden_print,函数 main 中引用了该符号
三、链接属性
1、变量的链接属性
- 全局变量具有外部链接
int global_var;
// 等效于
extern int global_var;
- 使用 static 关键字修饰的全局变量会变为内部链接
static int hidden_var;
- extern 必要,如果不加 extern,
file2.c
会认为要定义一个新变量,导致链接冲突
// file1.c
int global_var = 42; // 定义全局变量
// file2.c
extern int global_var; // 必须显式声明
2、函数的默认链接属性
- 函数具有外部链接
void func() {}
// 等效于
extern void func() {}
- 使用 static 关键字修饰的函数会变为内部链接
static void hidden_func() {}
- extern 可省略,但显式写出是可选的良好实践
// file1.c
void func() {}
// file2.c
void func(); // 可省略 extern