**:
c語言中全域性變數的定義與宣告困擾著許多c語言初學者。本文講述了全域性變數定義與宣告的用法,而且本為也將闡述這種用法的內在原理。我們先從兩個錯誤例子引入,以下兩個例程都在vc6.0平台上測試。
兩種錯誤例程
1.unresolved external symbol
例子包含兩個c檔案(test.c)和(first.c)和乙個標頭檔案(test.h)。下邊具體展示下它們的**。
test.h內容
#ifndef _test_h
#define _test_h
extern int count;
#endif
test.c內容
#include #include "test.h"
extern void fis_cal(void);
void main(void)
first.c內容
#include #include "test.h"
void fis_cal(void)
錯誤分析:test.h標頭檔案中宣告了全域性變數count,但是在兩個c檔案中都沒有對count進行定義,所以才會出現unresolved external symbol。
一種解決方法:隨便在兩個c檔案中加入一句「int count;」就ok了。例如我們加到test.c中,**如下。
#include #include "test.h"
extern void fis_cal(void);
int count;
void main(void)
說明:加入的「int count;」就是對count的定義,預設的將其初始化為0。
結論:這種錯誤原因是「只宣告未定義」。
2.multiply defined symbols found
還是如此,三個檔案。但是,兩個c檔案與例程一中的檔案一樣,改動的只是標頭檔案。
test.h內容
#ifndef _test_h
#define _test_h
int count;
#endif
錯誤分析:test.h標頭檔案中定義了全域性變數count,但是在兩個c檔案都通過「#include "test.h"」這句話對「int count;」進行了引用,所以造成了重複定義的錯誤。
一種解決方法:新增乙個「first.h」的標頭檔案,並且更改first.c的內容,具體更改如下。
first.h內容
#ifndef _first_h
#define _first_h
extern int count;
#endif
first.c內容
#include #include "first.h"
void fis_cal(void)
說明:經過這樣的修改,原來的test.c中就包含了count的定義,而first.c中就包含了對count的宣告,重複定義錯誤就得到解決。
結論:這種錯誤原因是「多個c程式都包含了定義全域性變數的標頭檔案」。
原理分析
我認為「int count;」是對全域性變數的定義,而「extern int count」是對全域性變數的宣告,目的是讓其他檔案也使用這個全域性變數。下邊我們來挖掘全域性變數的定義與宣告的內涵。
全域性變數要麼初始化(非零),要麼沒有初始化(為零)。非零時儲存在程式中的data段,零時儲存在程式的bss段。這談了程式(.bin或者.hex)的結構。我再講一下程式的啟動,程式在啟動(boot)過程中,通常都會執行乙個叫bootloader的引導程式,這個引導程式幹了很多事情,其中有一最重要的任務就是把程式(test段和rodata段)拷貝到記憶體,還包括data段的拷貝和bss段初始化。我們著重講一下data段的拷貝和bss段初始化。
我們的編譯器會為我們定義的全域性變數分配記憶體(位址),而且給我們的全域性變數賦初值(寫記憶體或清零),以後我們的程式就會根據需要來讀這個全域性變數(位址)或者修改這個全域性變數(寫記憶體)。初值為零時就在bss段,這個段初始化**會將這部分清零。初值非零時,初始化**會將全域性變數的初值拷貝到data段。
順便說一下c語言的儲存類說明符,這能幫助我們加深理解。
c語言的儲存類說明符
auto只在塊內變數宣告中被允許, 表示變數具有本地生存期。
extern出現在頂層或塊的外部變數函式與變數宣告中,表示宣告的物件具有靜態生存期, 連線程式知道其名字。
static可以放在函式與變數宣告中,在函式定義時,只用於指定函式名,而不將函式匯出到鏈結程式,在函式宣告中,表示其後邊會有定義宣告的函式,儲存型別static.在資料宣告中,總是表示定義的宣告不匯出到連線程式關鍵字。
一種更好的宣告與定義方式
test.h內容
#ifndef _test_h
#define _test_h
#ifdef globals
int count;
#else
extern int count;
#endif
#endif
test.c內容
#define globals
#include #include "test.h"
extern void fis_cal(void);
void main(void)
first.c內容
#include #include "test.h"
void fis_cal(void)
說明:這種方法可以只定義乙個標頭檔案實現在不同c檔案中分別實現定義與宣告。「#define globals」只在當前定義的test.c檔案中有效,所以在test.c中#include "test.h"預處理後,加入的是int count,而first.c中加入的"extern int count;"。其實還有一種書寫方法,也能實現這個效果。
test.h內容
#ifndef _test_h
#define _test_h
#ifdef globals
#define ext
#else
#define ext extern
#endif
ext int count;
#endif
C語言全域性變數定義與宣告技巧
在實際的程式設計中,全域性變數對我們程式設計來說既是喜又是淚,雖然說專案中盡量避免使用全域性變數,但總有些時候不得不使用它,並且可能使用得不少,各個模組可能有含有或多或少的幾個全域性變數,而當別的模組需要引用的時候,就必須extern它,造成你定義了一遍又宣告了一遍,這樣就稍顯得麻煩。下面介紹一種全...
C 全域性變數的宣告與定義
1.header1.h中宣告全域性變數,header1.cpp中定義全域性變數 header1.h ifndef header1 h define header1 h extern int g n 標頭檔案中必須加extern宣告全域性變數,不賦值 int g o 錯誤 int g o 10 錯誤 ...
全域性變數的定義宣告
c 中定義全域性變數要注意的地方 yandaren 1220 chinaunix部落格 c 中定義全域性變數要注意的地方 在c 中定義全域性變數是應該盡量在.cpp檔案中定義,而不要在.h 檔案中 定義,定義好了之後,可以在.件中利用 extern關鍵字進行 宣告.如果在.件中定義的話,多層包含可能...