C语言编程技巧 全局变量在多个c文件中公用的方法

在使用C语言编写程序时,经常会遇到这样的情况:我们希望在头文件中定义一个全局变量,并将其包含在两个不同的C文件中,以便这个全局变量可以在这两个文件中共享。举个例子,假设项目文件夹"project"下有三个文件:main.c、common.c和common.h。在这种情况下,我们希望声明一个字符型变量"key",使其在main.c和common.c中都可以被使用。

一种方法是在common.h文件中声明一个unsigned char类型的变量"key",然后由于main.c和common.c都包含了该头文件,因此这个"key"变量在两个文件中都是可见的,从而实现了共用。

回想起来确实有道理,但实际上在编写代码时,我们发现编译器给出了错误提示,大致是这样的:错误:L6200E:符号key重复定义(由common.o和main.o定义)。这意味着编译器认为我们重复定义了名为"key"的变量。造成这个问题的原因是#include命令会直接将头文件中的内容复制到#include的位置,导致main.c和common.c中都有了一份unsigned char key的定义。在C语言中,全局变量在整个项目(或称为工程)内都是可见的,因此项目中就存在了两个名为"key"的变量,编译器因此判定为重复定义。

正确的解决方法是使用extern关键字来声明变量为外部变量。具体做法是在其中一个c文件中定义全局变量"key",然后在另一个需要使用"key"的c文件中使用extern关键字进行声明,表明这个变量是在其他c文件中定义的全局变量。请注意我在这里所用的术语:定义和声明。例如,在main.c文件中定义变量"key",然后在common.c文件中使用extern关键字声明"key"为外部变量,这样这两个文件就能共享同一个变量"key"了。

(1)main.c文件

```c

#include "common.h"

unsigned char key_value;

```

(2)common.c文件:

```c

#include "common.h"

extern unsigned char key_value;

```

其实这就是变量定义和变量声明的区别。变量定义使用“数据类型+变量名称”的形式,编译器需要为其分配内存空间。而变量声明使用“extern 变量类型+变量名称”的形式,是告诉编译器该变量将在其他外部c文件中定义,此处只是引用它。编译器不会为其分配内存空间,直到遇到真正的变量定义时才会分配。

1、将普通变量定义为全局变量

如果是普通类型的变量,完全可以不使用*.h文件,在*.c文件中直接定义它,在调用该变量的文件中使用extern关键字进行声明。因为对于普通类型的变量,编译器是可以识别的。例如,在my.c文件中,我定义了一个char类型的数组name[10],那么在其他文件中只需使用extern char name[](由于是声明,数组的大小可以省略,但不建议使用指针,因为指针和数组有所不同)进行外部声明。这告诉编译器这个变量我已经定义过了,在其他地方具体怎样定义,你慢慢找吧。

2、将自定义结构体类型定义为全局变量

与普通类型不同,编译器不会自动识别我们自定义的类型,除非我们预先告知编译器。在这种情况下,头文件*.h的出现就很重要了。为了避免结构体类型占用额外的内存,我们可以将大结构体的定义放在*.h文件中。这样,无论多少次引用该头文件,内存都不会重复占用。而且这样做还有一个好处,其他文件可以通过include这个*.h文件,使得编译器可以识别我们的自定义类型。这样,我们就达到了预期的目的。

typedef struct _POSITION

int x;

int y;

}POSITION;

那么我可以在一个global.c文件中实现全局变量的定义,不过要include那个*.h文件,比如

/* ***global.c ******* */

include “global.h”

POSITION current,;

这样就定义了cunrrent这个变量,在别的文件中引用这个变量时,只要extern POSITION current;进行声明,然后就可以用了,不过这个文件也还得include "global.h" 因为如果不包含,在这个文件中是不识别POSITION类型的。

1.如何引用一个已经定义过的全局变量?

回答:可以通过引用头文件的方式,也可以使用extern关键字。如果通过引用头文件方式来引用头文件中声明的全局变量,假设我们在引用时出现了拼写错误,编译期间会报错,但如果我们使用extern关键字引用时出现了同样的错误,编译期间不会报错,而是在连接期间才会报错。

2.全局变量可不可以在多个.C文件中定义?为什么?

回答:可以。在不同的C文件中,可以用static关键字来声明同名的全局变量。虽然可以在不同的C文件中声明同名的全局变量,但前提是其中只能有一个C文件对该变量赋予初值,否则会在连接时报错。

关注私信小编,带你遨游代码世界!分享资料,学习方法,奇牛编程助你一臂之力!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/21201.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

量子机器学习解决方案新鲜出炉!Rigetti和ADIALab签署合作

​ (图片来源:网络) 近日,美国全栈量子经典计算的先驱Rigetti Computing宣布与阿拉伯联合酋长国的ADIA Lab签署了合作协议,双方将共同设计、构建、运行和优化量子计算解决方案,旨在解决概率分布分类问题&am…

spring通过文件属性注入bean和基于xml的bean的自动装配以及spring-eel表达式的使用加代码合集

😀前言 本章是spring基于XML 配置bean系类中第7篇讲解spring通过文件属性注入bean和基于xml的bean的自动装配以及spring-eel表达式的使用加代码合集 🏠个人主页:尘觉主页 🧑个人简介:大家好,我是尘觉&…

亚信科技AntDB数据库专家出席数据库标准研讨会并参与研讨

2023年7月12日,全国信息技术标准化技术委员会数据库标准工作组(SAC/TC28/WG31)秘书处组织召开数据库标准研讨会,会议围绕数据库标准工作组2023年上半年开展的标准编制情况进行交流。亚信科技AntDB数据库相关专家出席会议&#xff…

常用Web安全工具

Nessus 号称是世界上最流行的漏洞扫描程序,全世界有超过75000个组织在使用它。该工具提供完整的电脑漏洞扫描服务,并随时更新其漏洞数据库。Kali Linux预装了许多渗透测试软件,包括nmap 、Wireshark 、John the Ripper,以及Airc…

echarts图表渐变色 + 每个柱子不同颜色设置

echarts柱状图,默认所有柱子都是同一个颜色,显示效果差强人意,本文介绍如果修改成为每个柱子添加不同的颜色,以及如何添加渐变色,丰富图表的显示鲜果。先看效果: 每个柱子颜色不同 每个柱子都有自己的渐变…

Redis的缓存穿透、缓存击穿和缓存雪崩

目录 一、解释说明 二、缓存穿透 1. 什么是缓存穿透? 2. 常见的两种解决方案 (1)缓存空对象 (2)布隆过滤 3. 编码解决商品查询的缓存穿透问题 三、缓存雪崩 1. 什么是缓存雪崩? 2. 缓存雪崩解决方…

力扣 416. 分割等和子集

题目来源:https://leetcode.cn/problems/partition-equal-subset-sum/description/ C题解(思路来源代码随想录) : 背包问题有多种背包方式,常见的有:01背包、完全背包、多重背包、分组背包和混合背包等等。…

Prometheus实现系统监控报警邮件

Prometheus实现系统监控报警邮件 简介 Prometheus将数据采集和报警分成了两个模块。报警规则配置在Prometheus Servers上, 然后发送报警信息到AlertManger,然后我们的AlertManager就来管理这些报警信息,聚合报警信息过后通过email、PagerDu…

linux多线程

文章目录 linux多线程1. 相关概念1.1 线程概念详解线程 VS 进程线程的优点线程的缺点线程异常线程用途 1.2 页表详解 2. 线程控制2.0 POSIX线程库深入理解线程库使用C多线程接口在Linux环境创建多线程 深入理解线程id线程局部存储 2.1 线程的创建 - pthread_create线程创建时参…

计算机毕设 深度学习疫情社交安全距离检测算法 - python opencv cnn

文章目录 0 前言1 课题背景2 实现效果3 相关技术3.1 YOLOV43.2 基于 DeepSort 算法的行人跟踪 4 最后 0 前言 🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两…

C++设计模式创建型之单例模式

一、概述 单例模式也称单态模式,是一种创建型模式,用于创建只能产生一个对象实例的类。例如,项目中只存在一个声音管理系统、一个配置系统、一个文件管理系统、一个日志系统等,甚至如果吧整个Windows操作系统看成一个项目&#xf…

LNMP单节点部署

LNMP:是目前一套成熟的企业网站的应用模式,指的是一套协同工作的系统和相关软件。能够提供静态页面服务,也可以提供动态web服务。 L:linux系统 N:nginx网站服务,前端,提供前端静态页面,同时具有…

OC与Swift的相互调用

OC调用Swift方法 1、在 Build Settings 搜索 Packaging ,设置 Defines Module 为 YES 2、新建 LottieBridge.swift 文件,自动生成桥 ProductName-Bridging-Header.h 3、在 LottieBridge.swift 中,定义Swift类继承于OC类,声明 obj…

Postgresql源码(109)并行框架实例与分析

1 PostgreSQL并行参数 系统参数 系统总worker限制:max_worker_processes 默认8 系统总并发限制:max_parallel_workers 默认8 单Query限制:max_parallel_workers_per_gather 默认2 表参数限制:parallel_workers alter table tbl …

Linux搭建pikachu靶场(以centos为例)

Linux搭建pikachu靶场 Pikachu是一个使用PHP语言编写的Web漏洞测试靶场。下面是在CentOS 7上安装Pikachu靶场的步骤: 安装LAMP (Linux, Apache, MySQL, PHP) 堆栈: 首先,需要在CentOS 7服务器上安装LAMP堆栈。 安装Apache: yum i…

什么样的跨网文件安全交换系统 可实现安全便捷的文件摆渡?

进入互联网时代,网络的运算和数据管理能力助力各个行业高速发展,但同样带来了一些网络安全隐患,网络攻击、数据窃取、敏感信息泄露等问题。为此,我国出台了系列政策来全面提升银各行业系统网络安全整体防护水平,其中“…

HTTPS-RSA握手

RSA握手过程 HTTPS采用了公钥加密和对称加密结合的方式进行数据加密和解密 RSA握手是HTTPS连接建立过程中的一个关键步骤,用于确保通信双方的身份验证和生成对称加密所需的密钥 通过RSA握手过程,客户端和服务器可以协商出一个共享的对称密钥,…

如何解决电脑无声问题:排除故障的几种常见方法

大家好,今天我们来讨论一下处理电脑没有声音的故障。当你突然发现电脑静音无声时,需要逐步排除可能的问题,但总体而言,声音故障是相对容易解决的。接下来,我们将介绍一些排除电脑无声问题的方法。 第一步:…

路由器工作原理(第二十九课)

路由器工作原理(第二十九课) 一图胜过千言 1) 路由:数据从一个网络到另外一个网络之间转发数据包的过程称为路由 2) 路由器:连接不同网络,实现不同网段之间的通信 3)路由表:路由器选择数据的传输路径的依据 原始的路由表 Destination/Mask Proto Pre Cost …

Socks5代理:网络安全与爬虫之利器

一、Socks5代理:简介与工作原理 Socks5代理,全称为Socket Secure 5代理,是一种允许用户通过代理服务器进行网络连接的技术。它是Socks协议的最新版本,在网络安全和数据传输方面有着显著的优势。 Socks5代理与其他代理的不同之处在…