extern 、static 作为全局变量的使用与差异

同一项目中,不同文件间的同名同类型全局变量是不能互相使用的,那这时我们就可以使用extern、static来解决。

同时,虽然extern、static均可以修饰全局变量,但他们的意义却是大不相同。

目录

一.使用方式

二.区别


一.使用方式

extern: 

当我们在某一文件中定义了一个全局变量,只需要在其他文件中使用extern来声明该变量即可。

//文件1
int num = 5;//定义
//文件2
extern int num;//声明

注意:变量只能定义一次,即文件2中不能出现这样的代码:

extern int num = 3;//这是定义,与文件1冲突

 而且,不要在头文件中定义。因为,假如源文件中需要头文件定义的变量num,但源文件没有包含头文件,那么程序就会报错。

static:

static定义的变量,可以直接在其他包含同头文件的文件中使用。

//文件head.h
static int num = 5;
//文件2
#include"head.h"
void func()
{
    num++;
    cout << num << endl;
}

二.区别

1.static修饰的全局变量没有外部属性,extern修饰的具有外部属性。

这句话该怎么理解呢,假如我们有一个int类型全局变量num。

当用static修饰时,同项目不同文件中虽然都可以直接用num,但在一份文件中改变的num值不会影响到其他文件。这是因为本质上各个文件中的num是不同的,即地址不同

例:

//以下属于head.h文件
static int num = 0;
void func();
//以下属于文件1
#include"head.h"
void func()
{
	cout << "文件1中num初始化值:" << num << endl;
	num++;
	cout << "文件1中num++后值:" << num << endl;
	cout << "文件1中num地址:" << &num << endl << endl;
}
//以下属于文件2
#include"head.h"
int main()
{
    func();
	cout << "文件2中num初始化值:" << num << endl;
	cout << "文件2中num地址:" << &num << endl;
    return 0;
}

 我们发现,文件1与文件2的num地址是不同的,所以文件1中num值加1,但文件2中num值却没有改变。

但extern与之不同,改变某一个文件,其他文件中的num值也会改变,因为本质上是同一个地址。

例:

//以下属于head.h文件
extern int num;//声明
void func();
//以下属于文件1
int num = 0;//定义
void func()
{
	cout << "文件1中num初始化值:" << num << endl;
	num++;
	cout << "文件1中num++后值:" << num << endl;
	cout << "文件1中num地址:" << &num << endl << endl;
}
//以下属于文件2
extern int num;//声明
int main()
{
    func();
	cout << "文件2中num初始化值:" << num << endl;
	cout << "文件2中num地址:" << &num << endl;
    return 0;
}

 extern中,文件1与文件2的num地址相同,所以当文件1中num加1后,文件2中num也跟着改变了。

2.static必须是不同文件间都包含带有static的文件,extern可以是不同文件。

假如是不同文件的文件间想相互使用变量,要用extern。

假如包含同一头文件的文件间想相互使用变量,但又不希望其他文件的操作改变本文件变量,使用static。

3.static修饰全局变量不入符号表,extern修饰变量入符号表。

因为static修饰变量只在本文件中使用,但符号表中的是可以被其他文件调用的。也正是如此,在链接时,文件之间的static变量不会相互冲突。

细心的话我们会发现,假如在一个文件中定义一个全局变量num,其他文件中也定义的话会出现一个重定义错误。

//以下属于文件1
#include"head.h"
int num = 0;
//以下属于文件2
#include"head.h"
int num = 2;
int main()
{
	//func2();
	
	cout << "文件2中num初始化值:" << num << endl;
	cout << "文件2中num地址:" << &num << endl;
    return 0;
}

 这就是因为在汇编时,两个文件中的num都进入符号表。导致链接时发生了冲突。这时用static就能解决。

“代码胜于雄辩。”——林纳斯·托瓦兹(Linus Torvalds,Linux之父)


如有错误,敬请斧正

### LabVIEW 中数组类型的全局变量使用方法 在LabVIEW中,当考虑使用数组类型作为全局变量时需要注意其性能影响。由于每次从全局变量读取数据都会创建一份数据副本并保存于该全局变量中,对于大型数组而言这将显著增加内存消耗和处理时间[^1]。 #### 创建配置功能全局变量(FGV) 为了更高效地管理数组类型的数据,推荐采用功能全局变量(Functional Global Variable, FGV)。这类全局变量通过特定的动作输入参数控制VI的行为,并利用While循环内的未初始化移位寄存器存储操作结果。此方式不仅限定了对内部数据的操作模式,还增强了程序的安全性和稳定性[^2]。 ```labview // 定义一个简单的FGV VI结构如下: // 输入端口: // - Data In: 当Action为"Set"时提供要写入的新值(数组形式) // 输出端口: // - Data Out: 返回当前存储的数值或更新后的状态 // While Loop内含Shift Register用于保持最新版本的数据集, // 并依据传入的Action指令决定是返回现有内容还是应用新的更改。 ``` #### 实现细节说明 - **数据安全**:FGVs仅允许经由预设接口访问其中心资源,从而有效防止外部直接篡改核心数据[^4]。 - **性能优化**:相较于传统意义上的全局变量,FGVs减少了不必要的复制过程,特别是在频繁更新少量元素的情况下表现尤为明显。 #### 应用实例展示 假设存在一个需求是要动态维护一组测量样本点,则可以通过构建基于FGV机制的解决方案实现高效的增删查改功能。具体做法是在设计阶段精心规划好各个交互节点以及它们之间的逻辑关系,确保每一次变更都能及时反映到最终呈现给用户的界面组件上。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

就要 宅在家

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值