C語言:全域變數在多個c檔案中公用的方法

來源:互聯網
上載者:User

用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語言書,書中有詳細解釋和例子。

原文地址

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.