C语言学习之extern关键字

2023-11-15

1.了解extern

        1.extern是C语言的一个关键字,可以用来修饰函数与变量

        2.当extern修饰一个变量或函数时时,就是在声明这个变量(函数),告诉编译器在外部文件中已经这个变量(函数),要通过编译。 

 2.extern的用法

        1.在一个文件中引用其他文件的变量

        当我们一个项目中有多个.cpp文件时,往往需要在其中一个文件中使用另一个文件中定义的变量,如果我们直接使用,编译器就会报错: 

e462e8e09460434e80048850c3c514f3.png

由于编译文件1的时候编译器不认识g_val,以此编译失败

        这时我们就可以使用extern,如下:

//文件1.cpp代码

#include<stdio.h>
extern int g_val;    //声明外部符号g_val
int main()
{
	printf("%d", g_val);
}


//文件2.cpp代码
int g_val = 10;

        这时,代码就可以成功运行起来,打印出g_val的值。

        2.在一个文件中引用其他文件的函数

        对于函数,也是同理,当需要使用外部文件定义的函数时,需要使用extern关键字进行声明:

//文件1.cpp代码
#include<stdio.h>
extern void show();    //声明外部符号show()
int main()
{
	show();
}

//文件2.cpp代码
#include<stdio.h>
void show()
{
	printf("hello world");
}

运行结果如下:

hello world        

3.extern的注意事项

        在使用extern时我们可能会写出这样的代码 :

//文件1.cpp代码

#include<stdio.h>
extern int g_val=10;
int main()
{
	printf("%d", g_val);
}


//文件2.cpp代码
int g_val = 10;

上述代码是在引用外部变量g_val的时候同时对它进行赋值,当我们运行时,编译器就会报错,这个错误是在链接的时候发生的错误,为“找到一个或多个多重定义的符号” 。 


        产生错误的原因时什么呢 ?这就不得聊到定义与声明了。

        1.什么定义:

        定义是给变量或函数分配内存空间,在这同时可以为变量赋初值。

        2.什么是声明:

        声明是用来告诉编译器变量的名称和类型,使编译器知道存在着这个变量和类型,且不分配内存。

        3.结论

        由此我们可以得出以下两种结论:

        1.定义会对变量分配内存空间,而声明不会

        2.由于一个变量的存储空间是唯一的,因此定义不能重复定义,而声明可以重复声明。


         由此可以得出,当我们使用extern修饰变量且对它进行赋值的时候,这条语句就不是在对变量进行声明了,而是定义,因为声明一个变量编译器是不会分配内存空间的,而对于一个不存在的内存空间进行赋值操作,显然是不合理的。

        而当我们进行定义的时候,编译器在编译的时候并不会发现错误,但在多文件进行链接时,就会发现g_val这个全局变量同时在1.cpp和2.cpp进行定义,报出了重定义的错误。

4.extern与include

        1. include

        当我们有多个文件需要大量引用外部变量或函数的时候,如果使用extern,我们就需要在多个文件中大量使用extern,这样做效率显然会降低,代码也显得太过LOW。因此,我们通常将所有的全局变量和常用全局函数都写在一个.cpp文件中,然后用同名的.h文件放这些变量与函数的声明(即头文件),这样其他文件需要使用外部变量和函数时,就只需要包含其中的头文件即可,显得高效又简洁。如:

//文件1cpp代码
#include "2.h"
int main()
{
	show();
	printf("%d", g_val);
}

//文件2.cpp代码,用于定义与实现
#include "2.h"
int g_val = 10;
void show()
{
	printf("hello world");
}

//文件2.h代码,用于声明
#pragma once           //防止重复包含
#include<stdio.h>
extern int g_val;
void show();

这样,当我们需要使用2.cpp中的变量和函数时,就不需要再使用extern声明了

        2.extern的好处

        想必会有读者有疑问,include那么方便,那我们的extern关键字是不是没有用了?实则不然。原因如下:

        1.当头文件中有大量的变量与函数时,如果我们只需要其中的少量变量或函数时,我们使用include包含,显然会引入大量不需要的无关函数与无关变量,这样无疑会减慢程序预处理的过程,此时使用extern就可以有效缩短时间。

        2.在大工程中,一个头文件中经常会包含其他的头文件,这样层层嵌套下来,如果没有进行处理,往往会出现一个.c文件重复包含相同头文件的情况,而使用extern就不会出现这种情况。(当然,如果头文件进行适当的处理如“条件编译”,也能有效地避免重复包含的现象,这里先暂时不做详细讨论)


制作不易,能否点个赞再走呢qwq

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C语言学习之extern关键字 的相关文章

  • kudu clickhouse 添加字段删除字段

    impala 或hive 给指定kudu库中的表添加列 修改列并调整列位置 添加列 alter TABLE fact cpu supply category add columns supplier name string COMMENT
  • C语言—数据类型

    文章目录 1 基本数据类型 2 数组 字符数组和字符串 2 1 数组 2 2 字符数组与字符串 3 枚举类型 4 结构体和共用体 4 1 结构体 4 2 共用体 5 拓展 5 1 结构体内存分配 5 1 1 以结构体中占字节数最大的数据类型
  • IDEA和GIT关于文件中LF和CRLF问题

    问题描述 项目软件安装shell脚本上git仓库管理 但拉取后 上linux运行报错 问题思考 根据描述信息可以查看到 r字样 初步判别为换行符导致 1 将脚本文件移动至notepad 中 通过视图 gt 显示符号 gt 显示所有符号 一顿
  • 【Leetcode】111. 二叉树的最小深度

    题目描述 题解 递归遍历 记录深度 然后贪心地去更新结果 取min 考虑到这里还不够 需要加一层叶节点的判断 必须当前节点是叶子结点才能够做res的更新 否则可能会碰到这种情况 根结点左边没有子树 根结点右边有子树 结果递归下去发现深度是1
  • 轻量级网络:ResNeXt

    目录 insight Method Template Revisiting Simple Neurons Aggregated Transformations Model Capacity Experiments Experiments o
  • NVIDIA TensorRT简介

    一 NVIDIA TensorRT简介 二 NVIDIA TensorRT下载 根据自己硬件配置下载对应版本即可 本文以8 4 1为例 网址 https developer nvidia com nvidia tensorrt downlo

随机推荐

  • 分享一组开关按钮

    先看效果 再看代码
  • 网址备份

    1 搜索网站 http www google com 全球最强大的搜索网站 在语言学习中 它的功能至少包括 搜索新词可用之语境 确认某种搭配或用法是否准确 通过同时输入中文及 English 寻找可能存在的双语介绍 查询文学作品译本 了解某
  • Qt下QString与int 之间相互转换

    QString与int 之前相互转换 1 QString 转int QString str 100 int tmp str toInt 2 int 转QString int tmp 100 QString str QString numbe
  • python爬虫14:总结

    python爬虫14 总结 前言 python实现网络爬虫非常简单 只需要掌握一定的基础知识和一定的库使用技巧即可 本系列目标旨在梳理相关知识点 方便以后复习 申明 本系列所涉及的代码仅用于个人研究与讨论 并不会对网站产生不好影响 目录结构
  • 记linux内核处理bootargs到内核并加载模块时传入参数(module_param_named()等)

    昨晚 一网友问我如何把LCD反转一下输出 顿时不会 只会去看之前的dm3730的linux2 6 32的内核 偶然发现直接设置bootargs的参数到内核也许就可以啦 Linux以内核模块为核心 自动编译如系统后 所以的类似init cal
  • Webpack运行报错 Module parse failed

    自己本地项目运行报错 因为项目中使用package lock json固定了版本 项目中axios使用的0 21 1版本 可以正常运行 当删除package lock json执行npm install 然后axios版本为0 21 4 运
  • matlab filter函数_MATLAB 低通滤波器 low pass filter

    1 lowpass 函数 注意 只有2018年之后的matlab才有lowpass bandpass 函数 lowpass x fpass fs x 一维信号 fpass 截止频率 fs 采样频率 例子 两个频率的信号 一个是50HZ 振幅
  • air硬盘扩容 macbook_「技巧」苹果电脑硬盘拓展的5种方法,你知道吗

    前言 这是官网最新的MacBook Pro 13 提供的前两种配置 9999元起售 差价1500元 一样的外观 一样的处理器和内存 除了硬盘容量之外 其他配置全部相同 为了128G的容量多花1500元钱 值得吗 从成本上来说 是不值得的 同
  • 欧拉角与四元数

    以下文章摘自wiki百科 对于在三维空间里的一个参考系 任何坐标系的取向 都可以用三个欧拉角来表现 参考系又称为全局坐标系 是静止不动的 而局部坐标系则固定于刚体 随着刚体的旋转而旋转 参閲右图 设定 x y z轴为全局坐标系的参考轴 称
  • 软件程序流程图使用规范

    软件程序流程图使用规范 Amorphous 博客园 cnblogs com 目录 一 程序流程图的作用 二 画流程图常用软件 三 流程图中使用的符号 四 流程图采用的常用符号 五 循环流程图的画法 六 程序流程图的高级用法 七 基本结构 八
  • 算法训练day43

    文章目录 1049 最后一块石头的重量 II 求最大重量 思路分析 代码实现 494 目标和 求组合方法数 思路分析 动规方法 代码实现 总结思考 474 一和零 求二维背包的最大物品数 思路分析 代码实现 思考总结 1049 最后一块石头
  • springmvc / /* /img/**等问题

    在配置springmvc的前端控制器 DispatcherServlet的时候有三种配置方式 action 访问以 action结尾 由DispatcherServlet进行解析 第二种 所以访问的地址都由DispatcherServlet
  • 用Vmware和vm tools虚拟机装Linux Ubuntu16 配置anaconda python3环境 安装tensorflow/tflearn

    Authoried by Monana Contact me via hemonan vip 163 com 本教程适合虚拟机 也适合不用虚拟机直接用Linux系统的 0 安装前的准备答疑 1 很多人都会有疑问 我到底在虚拟机里装linux
  • filebeat 解析日志 并发送到Elasticsearch

    起先 是出于了解我的网站逐步前行STEP的访问情况而做一个Nginx日志统计分析的功能 首选的就是ELK 但是 由于Logstash占用内存和CPU占有率都不是我的小服务器能承受的 转而将logstash换成filebeat 因为fileb
  • 【计算机视觉

    文章目录 一 前言 二 试玩效果 三 研究背景 四 模型结构 五 Pre training objectives 六 CapFilt架构 七 Experiment 八 结论 一 前言 今天我们要介绍的论文是 BLIP 论文全名为 Boots
  • live555 实现一个最简单的RTSP服务器

    用live555中的库写了一个最简单的RTSPServer程序 仅用于学习目的 从下例的代码中 可以清析的明白RTSPServer的函数调用流程 cpp view plaincopyprint include
  • 人工智能期末复习

    1 人工智能 内涵和外延 英文 Artificial Intelligence 定义 能力方面 人工智能就是用人工的方法在机器 计算机 上实现的智能 或称机器智能 学科方面 是一门研究如何构造智能机器或智能系统 以模拟 延申和扩展人类智能的
  • 微信JSAPI支付v3流程(uniapp和node版)

    一 微信JSAPI支付 请提前准备好接入前的准备文档获取相关的配置数据 否则下面需要的数据你可能会比较懵 并且需要提前了解微信JSAPI支付文档 二 获取用户openid 获取openid方法例子 三 h5调起支付 1 第一种通过Weixi
  • springboot yml 配置文件注入Map,List

    文章转自 https blog csdn net sdzhangshulong article details 80124900 person lastName hello age 18 boss false birth 2017 12 1
  • C语言学习之extern关键字

    1 了解extern 1 extern是C语言的一个关键字 可以用来修饰函数与变量 2 当extern修饰一个变量或函数时时 就是在声明这个变量 函数 告诉编译器在外部文件中已经这个变量 函数 要通过编译 2 extern的用法 1 在一个