fatal error LNK1169: 找到一个或多个多重定义的符号或多个.c/.cpp文件想同时调用定义在.h文件里面的全局变量,防止重定义变量问题。
为什么.h文件中不能定义全局变量?
原因: 存在多次创建变量.如果头文件中可以定义全局变量,那么每个包含该头文件的文件里都会有该全局变量的定义.因为C语言的include是直接将文件嵌入到include这个地方的.
解决办法: 在头文件使用 extern 来声明该全局变量,然后在任意一个.cpp文件中定义该变量.全局变量是存放在静态区的.会被默认初始化为0.
原文:https://blog.csdn.net/jchnlau/article/details/49774599
C语言:全局变量在多个c文件中公用的方法
用C语言编写程序的时候,我们经常会遇到这样一种情况:希望在头文件中定义一个全局变量,然后包含到两个不同的c文件中,希望这个全局变量能在两个文件中共用。
举例说明:项目文件夹project下有main.c、common.c和common.h三个文件,其中common.h文件分别#include在main.c和common.c文件中。现在希望声明一个字符型变量key,在main.c和common.c中公用。如下图所示:
有人想,既然是想两个文件都用,那就在common.h中声明一个unsigned char key,然后由于包含关系,在main.c和common.c中都是可见的,所以就能共用了。
这种想法其实是很多初学者都会想到的,想起来确实有道理,但是实际写出来,我们发现编译的时候编译器提示出错,一般提示大概都类似于:Error: L6200E: Symbol key multiply defined (by common.o and 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文件中声明key变量为外部变量,这样这两个文件中就能共享这个变量key了,如下图所示。
代码如下(只写跟我们所说问题有关的部分):
(1)main.c文件
#include "common.h"
unsigned char key;
(2)common.c文件:
#include "common.h"
extern unsigned char key;
很多人看了可能糊涂,这里稍微说一下,其实就是变量定义和变量声明的区别,变量定义使用“数据类型+变量名称”的形式,编译器需要给他分配内存单元的;而变量声明使用“extern 变量类型+变量名称”的形式,是告诉编译器我这个变量将在其他外部c文件中定义,我这里只是在外部用它。编译器就不给他分配内存空间,而等到真正遇到变量定义的时候再给他分配内存空间。
由于很多人从开始学C语言就一直把定义变量叫声明变量,一开始就叫错了,所以导致现在分不清定义和声明的区别。要是还理解不了就想想函数的定义和声明,函数定义是编写函数功能实体,编译器要编译这个函数并且要分配内存空间,而函数声明并不生成函数功能实体,只是告诉编译器这是个函数,这个函数在后面将会定义实体,我这里只是提前用,编译器就会接着继续往下编译,如果子函数写在main函数之后,那么声明是必须的,如果不声明函数编译器都不知道这是个函数,编译就会报错。
说了这么多应该说明白了,如果还有问题可以参考谭浩强的那本C语言书,书中有详细解释和例子。
——————————————————————————————————————————
以下部分来源: http://blog.sina.com.cn/s/blog_5e87dc1201018qll.html
1、普通变量定义成全局变量
如果是普通类型,完全可以不用*.h文件,直接在*.c文件中定义,在调用文件处用extern 声明,因为对于普通类型,编译器是可以识别的。比如在一个 my.c文件中,我定义了char name[10];那么在别的文件中只要用extern char name[](由于是声明,一位数组可以省略大小,但不建议用指针,比较指针和数组是两回事)外部声明就可以了,告诉编译器这个变量我已经定义过了,具体怎样,你慢慢找吧。这符合常理,因为char是编译器能自主识别的类型。
2、自定义结构体类型定义成全局变量
不同于普通类型,如果不预先通知编译器,编译器是不会识别你自定义的类型的。这个时候,*.h文件便出现了。不是定义结构类型不占内存吗?那好,我大结构体的定义放在*.h文件中,这样一来,无论你incude无数次,内存都不会被占用的。而且这样还有个好处,在别的文件中可以include这个*.h文件,这样,在这个文件中,编译器就可以识别你的自定义类型了,目的不就达到了? 假如我在global.h中定义了
typedef struct _POSITION
{
int x;
int y;
}POSITION;
那么我可以在一个global.c文件中实现全局变量的定义,不过要include那个*.h文件,比如
include “global.h”
POSITION current,;
这样就定义了cunrrent这个变量,在别的文件中引用这个变量时,只要extern POSITION current;进行声明,然后就可以用了,不过这个文件也还得include "global.h" 因为如果不包含,在这个文件中是不识别POSITION类型的。
1.如何引用一个已经定义过的全局变量?
答:extern 可以用引用头文件的方式,也可以用extern关键字,如果用引用头文件方式来引用某个在头文件中声明的全局变理,假定你将那个编写错了,那么在编译期间会报错,如果你用extern方式引用时,假定你犯了同样的错误,那么在编译期间不会报错,而在连接期间报错。
2.全局变量可不可以定义在可被多个.C文件中?为什么?
答:可以,在不同的C文件中以static形式来声明同名全局变量。 可以在不同的C文件中声明同名的全局变量,前提是其中只能有一个C文件中对此变量赋初值,此时连接不会出错。
几个.C文件想同时调用定义在.H文件里面的全局变量,防止重定义变量问题。
首先,在.H文件里面加extern关键词声明全局变量,
然后,在.C文件中定义全局变量,变量定义不要放在头文件里。
在C文件里定义,在头文件里extern
例如:
module1.h
extern int iCounts;//声明全局变量
module1.c
int iCounts;//在任意一个.c或.cpp文件中定义该全局变量
#include "moudule1.h"
moudule2.c//其他C文件,包含.H文件后(#include "moudule1.h"),可以直接引用全局变量
Class
{
moudule2中的其它代码
}
“error LNK1169: 找到一个或多个多重定义的符号”的解决方法
废话不多说,下边举例子:
有三个文件,分别为a.h、a.cpp、b.cpp。
a.h和a.cpp的关系不多说,一看就明了,b.cpp也引用了a.h头文件,编译时通过,链接时出现“error LNK1169: 找到一个或多个多重定义的符号”的错误。也就是说单个文件是没有语法错误的,链接时出了问题。我在a.h中也加入了#ifndef..#define..#endif的头文件卫士,但是也是不行,查了下资料找到了原因。a.h中的变量在a.cpp和b.cpp中有使用,在编译时是不会出错,但是在链接时就会出现重定义的错误。解决方法就是在a.h声明的变量前加上extern的关键字,在b.cpp中不加extern关键字重新声明一次,就完美通过。
这其实是个很基础的问题,之所以犯这个错是因为单纯地以一个文件包含头文件的方式来看待。
原文:https://blog.csdn.net/BartonShan/article/details/54966420
C++多个文件共享同一头文件时全局变量的声明
前言
在编写非小型程序时,仅仅用到函数进行模块化是不够的,由于函数众多,在一个或几个文件中完成程序会造成单个程序文件过长。这样一来,不知不觉中提高的模块间的耦合性,扩大了程序的修改时间。这时候将功能分散到更多的模块中就变得尤为重要了。
那么,保持一个统一的结构,将不同文件纳入相同的一组文件中,并可以保持使用便成为了第一个问题。将原来在一个文件下的变量编写成不同文件都可以使用的变量就是我们需要解决的第二个问题。
通过活动预处理器块来避免重复编译
在文件过多的情况下,由于每个程序都会包含自己的头文件,在编译过程中,很有可能一个头文件被包含了多次,这时,进行编译会发生重复编译的错误。
例如:有两个子模块头文件:funtion1.h 和funtion2.h
funtion1.h中包含的头文件均是标准头文件,如:iostream, vector 等
funtion2.h中除了标准头文件还包括有:#include “funtion1.h”
这时,有一个文件包含以上两个头文件,如:
main.cpp中有如下内容:
:#include < iostream>
:#include “funtion1.h”
:#include “funtion2.h”
由于funtion2.h中已经包含了funtion1.h在main.cpp中,又被包含了一次,这样就发生了重复编译的错误。由于重复包括标准头文件不会导致这样的错误,所以需要我们对自行编写的头文件进行特殊说明,如
funtion1.h 中:
:#ifndef H_funtion1
:#define H_funtion1
:#include < fstream>
:#include < iostream>
:#endif
加入是否被编译的检查,这样的话就以避免重复编译相同的文件。
多个文件共享同一变量
多文件的组织
多个cpp文件要想纳入到同一个组织中,最简单的方式是,同时包含一个自行编写的头文件,在这个头文件中声明各个文件中要被其他文件所使用的函数签名,还有共用的变量。
共用的变量
函数的声明(不是定义),必须同时满足两点不同的要求:
变量类型前面有extern的修饰词。
没有初始化,或赋初值。
我们首先要做的就是在这个共用的头文件中声明各个文件间要共同使用的变量,如:
TotalHeader.h中
…
extern int a;
extern int b;
…
第二步,在其中一个文件中的全局位置定义变量,如:
funtion1.cpp中
:#inlcude “TotalHeader.h”
:#include …
int a = 0;
int b = 0;
void fun1(){
…
}
通过以上两步就可以实现多个文件中共享同一头文件时的全局变量声明
原文:C++多个文件共享同一头文件时全局变量的声明
示例程序: