C语言static和extern在头文件中注意事项

一、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

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值