多个源文件共享同个变量的方法

本文详细介绍了在C++中如何使用extern关键字声明全局变量,使其在多个源文件间共享。通过示例代码展示了extern的正确用法,以及如何避免编译错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  extern可置于变量或者函数前,以表示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找
其定义。
  另外,extern也可用来进行链接指定。

用法分析:
     在一个变量前加extern 比如:extern unsigned int Test;
编译器编译的时候,会把Test当成是外部的!会在其他地方寻找Test这个变量的定义,如果只加extern那么编译器就会报错!
比如这样:
     1>main.obj : error LNK2001:   无法解析的外部符号 "int Test" (?Test@@3HA)
     1>E:\wtl\test\test\Debug\test.exe :  fatal error LNK1120:    1个无法解析的外部命令
因为extern关键字只是说明我们从外部引用了一个变量,该变量的值叫Test,提醒编译器要到其他文件中查找该变量!

要想不报错,在其他文件加int Test 定义一个名字叫Test的变量吧。这样就能编译通过。

那么假设我有个main.c,source1.c,source2.c那么我想要在main里面定义一个变量,在source1.c跟source2.c都能使用该如何做?
很简单,先在main.c中定义一个值:int data;
那么在两个点c文件中都加上:extern int data,
这个变量能被这三个.c文件共用了,相当于一个全局变量。

示例代码:

//Main.c
#include
#include "source1.h"
#include "source2.h"
int data;
using namespace std;
void main()
{
    data = 4;
    adddata2();
    cout<<data<<endl;
    adddata1();
    cout<<data<<endl;
    cout<<"hello world "<<endl;
}

//Source1.c
#include "source2.h"
using namespace std;
extern int data;
void adddata2()
{
    data = data + 10;
}

//Source.h
#ifndef __SOURCE1_H__
#define __SOURCE1_H__
#include
void adddata1();
#endif
 
//Source2.c
#include "source1.h"
using namespace std;
extern int data;
void adddata1()
{
    data = data + 100;
}

//Source2.h
#ifndef __SOURCE2_H__
#define __SOURCE2_H__
#include
void adddata2();
#endif

 多个c文件共享同一个变量(全局变量)

当你声明一个变量的时候是这样 unsigned int data = 0;
当你在另一个源文件中想使用这个变量的时候。
只需要加关键字:extern unsigned int data;
(注意,这只是说明这个data是外部的变量,实际上并不分配存储空间的。也就是不能初始化!)

转载于:https://www.cnblogs.com/xiaosanxian/p/11141260.html

<think>我们正在讨论的是如何在多个源文件中使用普通全局变量。根据用[1]、[3]、[4]和[5],普通全局变量具有外部链接属性,可以在多个文件中共享,但需要正确使用`extern`关键字进行声明,并且只能在一个源文件中定义。 ### 核心步骤 1. **声明与定义分离**: - 在头文件(例如 `globals.h`)中使用 `extern` 声明全局变量(不分配内存)。 - 在**一个**源文件(例如 `globals.cpp`)中定义(分配内存并初始化)该全局变量。 - 其他源文件包含 `globals.h` 即可使用该全局变量。 2. **避免重复定义**: - 禁止在头文件中定义全局变量(不使用`extern`),否则多个源文件包含该头文件会导致重复定义错误[^3][^4]。 - 使用 `static` 修饰的全局变量具有内部链接属性,仅限本文件使用,不适用于跨文件共享[^5]。 ### 代码示例 #### 头文件:globals.h ```cpp #ifndef GLOBALS_H // 防止头文件重复包含 #define GLOBALS_H extern int global_counter; // 声明全局变量(不分配内存) #endif ``` #### 源文件:globals.cpp(定义全局变量) ```cpp #include "globals.h" // 定义并初始化全局变量(分配内存) int global_counter = 0; ``` #### 源文件:file1.cpp(使用全局变量) ```cpp #include <iostream> #include "globals.h" void increment_counter() { global_counter++; std::cout << "file1: global_counter=" << global_counter << std::endl; } ``` #### 源文件:file2.cpp(使用全局变量) ```cpp #include <iostream> #include "globals.h" void print_counter() { std::cout << "file2: global_counter=" << global_counter << std::endl; } ``` #### 主文件:main.cpp ```cpp #include "globals.h" // 声明其他文件中的函数(或使用头文件声明) void increment_counter(); void print_counter(); int main() { increment_counter(); // file1 中增加计数器 print_counter(); // file2 中打印计数器 return 0; } ``` #### 编译链接 - 编译所有源文件并链接: ```bash g++ globals.cpp file1.cpp file2.cpp main.cpp -o program ./program ``` - 输出: ``` file1: global_counter=1 file2: global_counter=1 ``` ### 关键点说明 1. **`extern`的作用**: - `extern`表示变量在其他地方定义,当前文件只是声明(不分配内存)[^1][^3]。 - 所有包含`globals.h`的文件都知道`global_counter`的存在,但实际内存仅在`globals.cpp`中分配。 2. **防止头文件重复包含**: - 使用 `#ifndef`、`#define`、`#endif` 或 `#pragma once` 避免头文件被多次包含导致的重复声明问题(虽然重复声明是允许的,但重复定义会出错)[^4]。 3. **初始化**: - 全局变量在定义时可以初始化(如`int global_counter = 0;`)。如果不初始化,默认为0(位于.bss段)[^5]。 ### 常见错误 - **重复定义**:在多个源文件中定义全局变量(例如在`file1.cpp`和`file2.cpp`中都写了`int global_counter;`)。必须确保**只有一个**定义。 - **忘记`extern`**:在头文件中直接写`int global_counter;`会导致每个包含该头文件的源文件都定义一个全局变量,链接时报错[^3]。 ### 相关问题 1. 如果多个源文件需要修改同一个全局变量,如何保证线程安全? 2. 在C++中,使用全局变量有哪些设计上的替代方案(如单例模式、命名空间封装)? 3. 静态全局变量(`static`修饰)和普通全局变量在链接时有什么区别?[^5] [^1]: 全局变量多个c文件中共用的方法。 [^3]: 跨文件共享全局变量需遵循“一次声明、一次定义、多次使用”原则。 [^4]: 在.h中用extern声明,在.cc中定义全局变量。 [^5]: static全局变量具有内部链接,普通全局变量具有外部链接。</think>### C++ 在多个源文件中使用普通全局变量方法 在 C++ 中,要在多个源文件共享普通全局变量,需遵循**"一次声明、一次定义、多次使用"**原则[^3]。核心方法是使用 `extern` 关键字声明变量,确保变量仅被定义一次。以下是具体步骤: #### 1. **创建头文件声明全局变量** 在头文件(如 `globals.h`)中使用 `extern` 声明变量: ```cpp // globals.h #ifndef GLOBALS_H // 防止重复包含 #define GLOBALS_H extern int shared_counter; // 声明全局变量(不分配内存) extern double shared_value; // 声明全局变量 #endif ``` - `extern` 表示变量在其他地方定义,此处仅为声明[^1][^3] - 头文件保护 `#ifndef` 防止重复包含 #### 2. **在单一源文件中定义全局变量** 在**一个**源文件(如 `globals.cpp`)中定义变量(分配内存): ```cpp // globals.cpp #include "globals.h" int shared_counter = 0; // 定义并初始化 double shared_value = 3.14; // 定义并初始化 ``` - 此处是变量的实际定义(分配内存) - 必须且只能在**一个**源文件中定义[^3][^4] #### 3. **在其他源文件中使用全局变量** 其他文件包含头文件后直接使用变量: ```cpp // file1.cpp #include "globals.h" void increment_counter() { shared_counter++; // 修改全局变量 shared_value *= 2; // 修改全局变量 } ``` ```cpp // file2.cpp #include <iostream> #include "globals.h" void print_values() { std::cout << "Counter: " << shared_counter // 读取全局变量 << ", Value: " << shared_value; // 读取全局变量 } ``` #### 4. **主程序调用** ```cpp // main.cpp #include "globals.h" void increment_counter(); // 声明函数 void print_values(); // 声明函数 int main() { increment_counter(); // 修改全局变量(file1.cpp) print_values(); // 输出全局变量(file2.cpp) return 0; } ``` #### 编译运行 ```bash g++ globals.cpp file1.cpp file2.cpp main.cpp -o program ./program # 输出: Counter: 1, Value: 6.28 ``` ### 关键原理说明 1. **`extern` 的作用**: - 声明变量但不分配内存,通知编译器变量在其他位置定义[^1][^3] - 允许多个文件一全局变量 2. **避免重复定义**: - 普通全局变量具有**外部链接**属性(可在文件间共享)[^5] - 若在头文件中定义变量(无 `extern`),包含该头文件的每个源文件都会创建独立副本,导致链接错误[^3][^4] 3. **与 `static` 全局变量的区别**: | 特性 | 普通全局变量 | static 全局变量 | |------|-------------|----------------| | 链接属性 | 外部链接(可跨文件) | 内部链接(仅本文件)[^5] | | 作用域 | 全局 | 文件内 | | 共享性 | 可跨文件共享 | 不可共享 | ### 常见错误及解决 1. **重复定义错误**: ```bash multiple definition of `shared_counter' ``` **原因**:在多个源文件中定义了变量(如误在头文件中定义)<br> **解决**:确保仅在**一个**源文件中定义变量 2. **未定义用错误**: ```bash undefined reference to `shared_counter' ``` **原因**:声明了 `extern` 变量但未在任何地方定义<br> **解决**:在某个源文件中添加定义(如 `int shared_counter;`) 3. **命名冲突**: **解决**:使用命名空间封装全局变量 ```cpp // globals.h namespace GlobalVars { extern int counter; } ``` ### 相关问题 1. 如何在多线程环境中安全使用全局变量? 2. 使用全局变量与单例模式(Singleton)有何优劣? 3. C++17 的 `inline` 变量如何简化全局变量定义?[^5] 4. 静态全局变量(static)在哪些场景下更适用?[^5] [^1]: 全局变量多个c文件中共用的方法 [^3]: 跨文件共享全局变量需遵循"一次声明、一次定义、多次使用"原则 [^4]: 在.h中用extern声明,在.cc中定义全局变量 [^5]: static全局变量具有内部链接,普通全局变量具有外部链接
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值