extern语句怎么用
时间: 2023-09-17 08:06:34 浏览: 82
`extern` 关键字用于在一个源文件中声明一个变量或函数,该变量或函数在另一个源文件中定义。这样做可以使得多个源文件共享同一个变量或函数。
在声明变量时,`extern` 关键字告诉编译器该变量在其他文件中定义,而在定义变量时,则不需要使用 `extern` 关键字。
例如,在一个源文件中声明一个全局变量 `x`,并在另一个源文件中定义该变量:
```
// 文件1:声明全局变量 x
extern int x;
// 文件2:定义全局变量 x
int x = 1;
```
在文件1中,我们使用 `extern` 关键字来告诉编译器变量 `x` 在其他地方定义。在文件2中,我们定义了变量 `x` 并初始化为 1。
注意:在 C++ 中,全局变量和函数默认情况下是外部链接(external linkage),可以被其他文件访问。在 C 中,全局变量和函数默认情况下是静态链接(static linkage),只能在当前文件中访问。如果需要在其他文件中访问,需要使用 `extern` 关键字进行声明。
相关问题
extern语句
### C/C++ 中 `extern` 的作用
在 C 和 C++ 编程语言中,`extern` 是一种存储类说明符,用于声明变量或函数的存在而不定义它们。它告诉编译器该变量或函数已经在其他文件或其他地方被定义了,当前只需要知道它的存在即可。
#### 1. **`extern` 声明全局变量**
当多个源文件共享同一个全局变量时,可以使用 `extern` 来声明这个变量。这样可以在不同的文件之间访问同一内存地址中的数据[^1]。
以下是具体示例:
假设有一个头文件 `b.h` 定义了一个结构体和两个函数原型:
```cpp
// b.h
#ifndef B_H
#define B_H
struct student {
char name[20];
int age;
};
void get_stu(student& s);
void set_stu();
#endif // B_H
```
另一个文件 `student.cpp` 实现这些功能并初始化一个学生对象:
```cpp
// student.cpp
#include "b.h"
#include <iostream>
using namespace std;
student stu1 = {"Alice", 20};
void get_stu(student& s) {
cout << "Name: " << s.name << ", Age: " << s.age << endl;
}
void set_stu() {
cin >> stu1.name >> stu1.age;
}
```
最后,在主程序文件 `main.cpp` 使用 `extern` 关键字引入外部定义的学生对象 `stu1` 并调用其操作函数:
```cpp
// main.cpp
#include <iostream>
#include "../include/b.h"
using namespace std;
extern student stu1; // 外部变量声明
int main() {
get_stu(stu1); // 输出初始状态
set_stu(); // 修改学生信息
get_stu(stu1); // 再次输出修改后的状态
return 0;
}
```
在这个例子中,通过 `extern` 将 `student.cpp` 文件里实际创建的对象 `stu1` 引入到了 `main.cpp` 当中[^1]。
#### 2. **`extern` 声明函数**
虽然通常不需要显式地用 `extern` 来声明函数(因为默认情况下所有的函数都是具有外部链接性的),但在某些特殊场景下还是需要用到的。比如在一个单独命名空间或者模块内部隐藏实现细节的时候。
例如:
```cpp
// utils.cpp
#include <string>
std::string internal_function(const std::string& input){
return "Processed:" + input;
}
```
如果希望别的部分能够看到此函数,则需如下这般处理:
```cpp
// utils.h
#ifdef UTILS_EXPORTS
#define UTILS_API __declspec(dllexport)
#else
#define UTILS_API __declspec(dllimport)
#endif
UTILS_API extern const char* external_function(const char*);
// utils.cpp
const char* external_function(const char* str){
auto result = internal_function(str);
return result.c_str();
}
```
这里展示了如何利用 `extern` 结合宏定义控制动态库导出导入行为[^2]。
#### 3. **注意事项**
- 如果只是单纯声明而未提供真正的定义位置的话,那么链接阶段会出现错误提示找不到对应实体。
- 对于常量而言,默认就是静态局部性质即隐含 static 属性;因此若要跨文件引用则也得加上 explicit extern 明确指出[^3]。
### 总结
综上所述,`extern` 主要是用来解决不同翻译单元间资源共享问题的一种机制。无论是对于变量亦或是函数来说都发挥着重要作用。
extern结构体
### C/C++ 中 `extern` 关键字与结构体的结合用法
在 C 和 C++ 编程中,`extern` 是一种用于声明变量或函数的关键字,表示该变量或函数是在其他源文件中定义的。当涉及到结构体时,可以利用 `extern` 来实现跨文件访问全局结构体实例。
#### 基本原理
如果在一个文件中定义了一个结构体类型的全局变量,并希望在另一个文件中使用它,则可以在第二个文件中通过 `extern` 进行声明[^1]。这样做的目的是避免重复定义同一个变量,从而保持数据的一致性和唯一性。
#### 示例代码说明
以下是具体的例子展示如何结合 `extern` 和结构体:
##### 文件 a.h (头文件)
```cpp
// a.h
#ifndef A_H
#define A_H
struct student {
char name[20];
int age;
float score;
};
#endif // A_H
```
此部分定义了名为 `student` 的结构体类型并将其暴露给其他 `.cpp` 或 `.c` 文件使用[^2]。
---
##### 文件 a.cpp (定义全局结构体实例)
```cpp
// a.cpp
#include "../include/a.h"
#include <iostream>
struct student stu1 = { "tom", 18, 90 };
void get_stu(struct student stu) {
std::cout << stu.name << std::endl;
std::cout << stu.age << std::endl;
std::cout << stu.score << std::endl;
}
```
在此处创建了一个属于 `student` 类型的全局对象 `stu1` 并初始化其成员值。
---
##### 文件 main.cpp (外部引用)
```cpp
// main.cpp
#include "../include/a.h"
#include <iostream>
extern struct student stu1;
int main() {
std::cout << "Student Name: " << stu1.name << std::endl;
std::cout << "Student Age: " << stu1.age << std::endl;
std::cout << "Student Score: " << stu1.score << std::endl;
return 0;
}
```
这里通过 `extern` 声明告诉编译器 `stu1` 实际上是一个位于其他地方(即 `a.cpp`)定义的对象。因此,在链接阶段会找到真正的内存地址绑定上去完成整个程序运行逻辑构建过程。
---
#### 注意事项
- **头文件保护**:为了防止多次包含相同的头文件造成冲突问题,通常会在每个`.h`头部加入宏控制语句如上述中的 `#ifndef/#define/#endif` 组合。
- **命名空间污染**:虽然可以直接写成裸形式比如直接书写 `struct student stu1;` 而不加任何修饰符,默认情况下它是具有静态存储期作用域仅限于当前翻译单元内的局部变量;但如果想让它成为真正意义上的共享资源就必须加上显式的关键词 `extern` 才能突破这一限制条件达到预期效果[^3].
- **类型安全检查**:由于C++支持更严格的类型检测机制所以建议尽可能采用现代风格做法例如借助标准库容器或者智能指针等方式替代原始指针操作减少潜在风险隐患提升软件质量水平[^4].
---
阅读全文
相关推荐














