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語言:全局變量在多個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++多個文件共享同一頭文件時全局變量的聲明

 

示例程序:

https://pan.baidu.com/s/1w17xs2W8tMgFc5OGRDvLfg

https://pan.baidu.com/s/1GPwb1FVYDyoEu5mSnAihbQ


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM