当前位置: 首页 > news >正文

c++ extern 关键字详解

extern关键字在C++中用于声明变量或函数的外部链接。它通常用于以下几种场景:

  1. 声明全局变量:在一个文件中定义变量,在其他文件中使用extern声明该变量,以便在多个文件之间共享。
  2. C和C++混合编程:在C++代码中引用C语言编写的函数或变量时,使用extern "C"来防止名称修饰(name mangling),从而使C++编译器能够正确链接C函数。

extern关键字的使用示例

1. 声明全局变量
假设有两个文件,file1.cpp 和 file2.cpp:

file1.cpp:

#include <iostream>int globalVar = 42; // 定义全局变量void printGlobalVar() {std::cout << "Global variable: " << globalVar << std::endl;
}

file2.cpp:

#include <iostream>// 声明全局变量(不定义,只声明)
extern int globalVar;void modifyGlobalVar() {globalVar = 100;
}int main() {printGlobalVar();   // 调用 file1.cpp 中的函数modifyGlobalVar();  // 修改全局变量printGlobalVar();   // 打印修改后的全局变量return 0;
}

编译并链接这两个文件:

g++ file1.cpp file2.cpp -o main
./main

输出:

Global variable: 42
Global variable: 100

2. C和C++混合编程
假设有一个C语言的头文件和源文件c_code.h和c_code.c,以及一个C++文件main.cpp。

c_code.h:

#ifndef C_CODE_H
#define C_CODE_Hvoid c_function();#endif

c_code.c:

#include "c_code.h"
#include <stdio.h>void c_function() {printf("This is a C function.\n");
}

main.cpp:

#include <iostream>
extern "C" {#include "c_code.h" // 使用 extern "C" 防止名称修饰
}int main() {c_function(); // 调用 C 函数return 0;
}

编译并链接这两个文件:

g++ main.cpp c_code.c -o main
./main

输出:

This is a C function.

详细说明

  1. 声明与定义:

    • 声明:告诉编译器变量或函数的名称和类型,但不分配内存。例如,extern int x;只是声明变量x,不定义它。
    • 定义:不仅声明变量或函数,还分配内存。例如,int x = 42;定义并初始化变量x。

2. 名称修饰(Name Mangling):

  • C++编译器会对函数名称进行修饰,以支持函数重载。这可能导致C语言编写的函数在C++代码中无法正确链接。extern
    "C"阻止名称修饰,使C++编译器使用C语言的链接规范。

3. 作用域:

  • extern变量的作用域是全局的,多个文件可以共享相同的变量。这在大型项目中尤其有用,允许模块之间共享数据。

注意事项

  1. 初始化:
    • extern变量不能在声明时初始化,只能在定义时初始化。例如,extern int x = 42;是错误的,应该是int x = 42;。
  2. 避免重复定义:
    • 确保每个全局变量只有一个定义。在其他文件中使用extern声明变量,而不是重复定义。

通过合理使用extern关键字,可以在C++程序中实现模块化和代码共享,提高代码的可维护性和可扩展性。

http://www.lryc.cn/news/377250.html

相关文章:

  • 计算机网络:运输层 - TCP 流量控制 拥塞控制
  • Python学习打卡:day10
  • 新书速览|Ubuntu Linux运维从零开始学
  • [Qt的学习日常]--窗口
  • Vue发送http请求
  • 学习使用js和jquery修改css路径,实现html页面主题切换功能
  • (转)请介绍一下Redis的数据淘汰策略
  • APP自动化测试-Appium常见操作之详讲
  • 写给大数据开发:谈谈数仓建模的反三范式
  • Stable diffusion 3 正式开源
  • 如何配置node.js环境
  • python tensorflow 各种神经元
  • Gone框架介绍27 - 再讲 Goner 和 依赖注入
  • 【Python/Pytorch 】-- 滑动窗口算法
  • Clickhouse集群create drop database可删除集群数据库或只删除本地数据库
  • 【docker】adoptopenjdk/openjdk8-openj9:alpine-slim了解
  • Vscode interaction window
  • 后端数据null前端统一显示成空
  • 【设计模式深度剖析】【9】【行为型】【访问者模式】| 以博物馆的导览员为例加深理解
  • Salesforce‘s 爱因斯坦机器人助手引领工业聊天机器人时代
  • Day7—zookeeper基本操作
  • 计算机组成原理---Cache的基本工作原理习题
  • springboot项目中切数据库(mysql-> pg)带来的适配问题:typeHandler
  • 从零开始的<vue2项目脚手架>搭建:vite+vue2+eslint
  • Hadoop升级失败,File system image contains an old layout version -64
  • [机器学习算法]决策树
  • springboot应用cpu飙升的原因排除
  • 反激开关电源EMI电路选型及计算
  • vue3前端对接后端的图片验证码
  • 【Unity】RPG2D龙城纷争(四)要诀、要诀数据集