一、static
前言:
static修饰局部变量:延长变量声明周期
static修饰全局变量或函数:限制其作用域只在当前源文件中有效
1.1在头文件中用static修饰变量
1,当头文件中有static变量,那么在所有包含该头文件的源文件中都定义了仅自己可见的static变量,不同源文件中使用的也是仅属于自己的static变量,并不是同一个(每个包含的.c拷贝自己的一份static修饰的全局变量,在各自的.c中修改值不影响其它.c文件)。
2,当头文件中定义了普通的全局变量,所有包含该头文件的源文件都会定义一个相同名称的全局变量,编译时不会报错,但当所有 .o 文件被链接成一个可执行文件时,如果多个 .o 文件中有相同名字的全局变量,链接器解析所有的全局变量的引用时会报错,因为它不知道应该链接哪一个。
1.2 在头文件中用static修饰函数 --谨慎使用
如果在头文件中声明了static函数,那么所有包含它的源文件都会存在该static函数声明。如果一些源文件要使用该函数,由于static函数仅在当前源文件作用域可见,那么必须在每一个要使用该函数的源文件中都有函数实现,如果仅在一个源文件中实现,其他源文件使用则会编译错误,因为这个实现对于其他源文件是不可见的。
1. 3 static修饰结构体中的成员无效 --错误
在 C 语言中,不能直接在结构体定义时为成员添加 static
修饰符。结构体的成员通常是作为实例的一部分进行定义的,而 static修饰符通常用于控制变量的生命周期和作用域,与结构体成员的实例化过程不兼容。
示例(无效):
struct MyStruct {
static int x; // 错误:无法在结构体中使用 static 修饰成员
};
二、extern
2.1extern修饰头文件中变量
sharedVariable在source1.c中定义,并在source2.c中使用。两个源文件都包含了header.h,它们共享同一个变量实例,而不是各自有自己的拷贝。
例如:
header.h:
#ifndef HEADER_H
#define HEADER_H
extern int sharedVariable; // 声明一个外部变量
#endif // HEADER_H
source1.c:
#include "header.h"
int sharedVariable = 10; // 定义并初始化外部变量
source2.c:
#include "header.h"
void someFunction() {
sharedVariable += 5; // 可以访问和修改外部变量
}
2.2 使用 extern 关键字的注意事项
作用范围:extern 声明的变量或函数在当前文件中有效。如果需要在多个文件中使用该函数或变量,可以在公共头文件中声明。
extern 声明的变量不能在声明时赋初始值。例如:
extern int x = 10; // 错误
可以在多个文件中使用extern声明同一个全局变量或函数,但只能在一个文件中定义它们。将 extern 声明放在头文件中,供多个源文件包含,这是一个常见的做法。例如:
// global.h
extern int globalVariable; // 声明全局变量
extern void printMessage(); // 声明函数
另外:
在a.c中写的函数,在a.h对该函数声明,在b.c中使用a.c中的函数直接包含a.h即可。因为在头文件中声明函数时,extern
关键字是可选的,extern
关键字通常用于声明全局变量。对于函数声明,默认就是外部链接。
3 其它
如果你在头文件中直接定义了一个全局变量,那么它会在每个包含该头文件的源文件中都被定义一次,导致 多重定义 问题。
假设你在头文件中直接定义了一个变量,例如:
// header.h
int myGlobalVar = 10; // 直接在头文件中定义变量
然后在多个源文件中包含了这个头文件:
// file1.c
#include "header.h"
void modifyVar1() {
myGlobalVar = 20; // 修改 myGlobalVar
}
// file2.c
#include "header.h"
void modifyVar2() {
myGlobalVar = 30; // 修改 myGlobalVar
}
编译错误:
multiple definition of `myGlobalVar`
注:有的编译器不报错。今天接手一套代码,我编译报错,找了好久才发现前人在头文件中定义的变量在多个源文件包含,导致报上面这个编译错误,由于涉及太多,可在头文件中定义的变量前加static避免(要确保该变量只在一个源文件中被使用);
static 和 extern不能同时用于同一个变量。
static 和 extern 是两个具有相反含义的关键字。
• static 关键字用于声明一个变量时,会限制该变量的作用域,使其只能在声明它的文件内部访问。这意味着即使它是一个全局变量,它也不会被其他文件看到。
• extern 关键字用于声明一个变量时,表示该变量是在其他地方定义的,允许当前文件访问到这个变量。 extern 通常用于声明全局变量,以便在多个文件中访问同一个全局变量。如果你尝试将 static 和 extern 同时用于一个变量,编译器会报错,因为这两个关键字是互斥的。
参考链接:https://blog.youkuaiyun.com/zhu_superman/article/details/134987096