c/c++多文件编译报重复定义的问题

本文详细解释了在使用微软编译器如VS2017时遇到的LNK2005和LNK1169错误,即变量重复定义的问题。探讨了全局变量的正确声明与定义方法,避免在.h文件中定义全局变量,而应使用extern关键字在.c文件中进行定义。

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

  相信使用微软编译器的大家(例如vs2017)肯定会遇到这样的一个问题,说你的某个变量重复定义,就像这个样子。
当然我这个只是一个例子
  具体可能是代号为LNK2005和LNK1169。这个错误可能会出现在你是第一次开始使用多文件来编写程序。现在,我们就来探讨一哈这个问题。首先来介绍几个概念。
  在C Primer Plus 一书中,在第12章 存储类,链接和内存管理中,有链接这样一个概念。

具有代码块作用域和函数原型作用域的变量具有空链接。这意味着它们是由其定义所在的代码块或函数原型所私有的。
具有文件作用域的变量可能就有空链接或者外部链接。
一个具有外部链接的变量可以在一个多文件程序中被使用,而一个具有内部链接的变量可以在一个文件中任何地方使用

至于什么时具有文件作用域,代码块作用域,大家不懂的话就自己去查一下,这里就不多讲了。
  回归正题,为什么大家程序编译后会出现重复定义捏?你可能之前还看到过说你在你的文件加上几行这样的代码就好了:

#ifndef _STATEMENT_H
#define _STATEMENT_H
...
...
#endif

但是你会发现你可能加上去还是没有解决问题!所以,在这里你就的好好了解一哈这个原因了。
  大家产生这个问题的原因可能会和我的不一样,但是你可听一哈我的分析,再去看看自己的代码。原因就在于我自己想要定义一个全局变量,但是把它定义到我的.h文件中去了(因为我当时是想说,反正以后别的文件包含这个.h文件,就可以使用该变量了。)但是,也就是因为这样,编译报错了。原因就是我没有遵守“.h就只要声明,不要定义”规矩。你可以去把你要定义的全局变量放在.c文件中定义,而.h文件中使用extern来申明该变量。总之:你的全局变量定义最好就在.c文件中定义,而他的申明可以放在.h文件中,使用extern 扩展其定义。方便之后其他文件的调用。
  上面讲的是解决方法。那之前讲的那个定义有什么用处捏。为了就是解释一个一个问题。举个例子:
在a.c文件中,你有一个全局变量的定义:static int i;
在b.h文件中你也写了extern int i;
然后你想要在main.cpp中通过#include"b.h"来使用变量i。但是你会发现编译就会报错。
无法解析的外部指令错误
原因就是static变量是一个具有内部链接的变量,其作用域只有该文件内部,在这里就是a.c文件中才可以使用。但是extern int i;必须要求其变量具有文件定义域。所以,这里可能会报一个无法解析的外部指令这样一个问题。就是因为这里b.h文件中extern int i;并没有起到声明a.c文件中static int i;变量这样的目的。(以下内容是自己的理解)这里相当于又声明了int i;但是没有给其分配内存,之后你去使用它时,就会报无法解析的外部指令这样的错误。仔细一想,好像之前定义的函数,但是没有具体实现函数,而直接去使用函数的时候,也会报这样的错误。
  上面的解释都没有研究其本质,本质还得去看编译器是怎么处理的,这样才能将其完全弄清楚。但是我还没有到可以研究编译器的地步,但是我会继续努力的,加油!
  下面的百度百科那篇关于extern 讲解的还是十分好的,可以仔细看看!

参考过的文章,值得去看

https://baike.baidu.com/item/extern/4443005?fr=aladdin
https://zhidao.baidu.com/question/625405489688417844.html?qq-pf-to=pcqq.c2c

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值