http://blog.csdn.net/zhanglianpin
全域變數應該是得到記憶體配置且可以被其他模組通過C語言中extern關鍵字調用的變數。因此,必須在 .C 和 .H 檔案中定義。這種重複的定義很容易導致錯誤。以下討論的方法只需用在標頭檔中定義一次。雖然有點不易懂,但使用者一旦掌握,使用起來卻很靈活。表1.2中的 定義出現在定義所有全域變數的.H標頭檔中。
程式清單 L 1.2 定義全域宏。
#ifdef xxx_GLOBALS
#define xxx_EXT
#else
#define xxx_EXT extern
#endif
.H 檔案中每個全域變數都加上了xxx_EXT的首碼。xxx代表模組的名字。該模組的.C檔案中有以下定義:#define xxx_GLOBALS
#include "includes.h"
當 編譯器處理.C檔案時,它強制xxx_EXT(在相應.H檔案中可以找到)為空白,(因為xxx_GLOBALS已經定義)。所以編譯器給每個全域變數分配 記憶體空間,而當編譯器處理其他.C檔案時,xxx_GLOBAL沒有定義,xxx_EXT被定義為extern,這樣使用者就可以調用外部全域變數。為了說 明這個概念,可以參見uC/OS_II.H,其中包括以下定義:#ifdef OS_GLOBALS
#define OS_EXT
#else
#define OS_EXT extern
#endif
OS_EXT INT32U OSIdleCtr;
OS_EXT INT32U OSIdleCtrRun;
OS_EXT INT32U OSIdleCtrMax; 同時,uCOS_II.H有中以下定義:#define OS_GLOBALS
#include “includes.h” 當編譯器處理uCOS_II.C時,它使得標頭檔變成如下所示,因為OS_EXT被設定為空白。INT32U OSIdleCtr;
INT32U OSIdleCtrRun;
INT32U OSIdleCtrMax;
這樣編譯器就會將這些全域變數分配在記憶體中。當編譯器處理其他.C檔案時,標頭檔變成了如下的樣子,因為OS_GLOBAL沒有定義,所以OS_EXT被定義為extern。extern INT32U OSIdleCtr;
extern INT32U OSIdleCtrRun;
extern INT32U OSIdleCtrMax;
在這種情況下,不產生記憶體配置,而任何 .C檔案都可以使用這些變數。這樣的就只需在 .H 檔案中定義一次就可以了。總結:在嵌入式c語言定義一個全域變數,而且希望此全域變數在其他c檔案中和在工程彙編中使用此變數的話。我們在標頭檔裡定義了一個全域變數,在其它檔案裡用extern 關鍵字引用即可。而如果每個檔案都引用這個標頭檔會產生重複定義全域變數的問題。我們使用這種條件編譯就能解決此問題。
全域變數應該是得到記憶體配置且可以被其他模組通過C語言中extern關鍵字調用的變數。因此,必須在 .C 和 .H 檔案中定義。這種重複的定義很容易導致錯誤。以下討論的方法只需用在標頭檔中定義一次。雖然有點不易懂,但使用者一旦掌握,使用起來卻很靈活。表1.2中的 定義出現在定義所有全域變數的.H標頭檔中。
程式清單 L 1.2 定義全域宏。
#ifdef xxx_GLOBALS
#define xxx_EXT
#else
#define xxx_EXT extern
#endif
.H 檔案中每個全域變數都加上了xxx_EXT的首碼。xxx代表模組的名字。該模組的.C檔案中有以下定義:#define xxx_GLOBALS
#include "includes.h"
當 編譯器處理.C檔案時,它強制xxx_EXT(在相應.H檔案中可以找到)為空白,(因為xxx_GLOBALS已經定義)。所以編譯器給每個全域變數分配 記憶體空間,而當編譯器處理其他.C檔案時,xxx_GLOBAL沒有定義,xxx_EXT被定義為extern,這樣使用者就可以調用外部全域變數。為了說 明這個概念,可以參見uC/OS_II.H,其中包括以下定義:#ifdef OS_GLOBALS
#define OS_EXT
#else
#define OS_EXT extern
#endif
OS_EXT INT32U OSIdleCtr;
OS_EXT INT32U OSIdleCtrRun;
OS_EXT INT32U OSIdleCtrMax; 同時,uCOS_II.H有中以下定義:#define OS_GLOBALS
#include “includes.h” 當編譯器處理uCOS_II.C時,它使得標頭檔變成如下所示,因為OS_EXT被設定為空白。INT32U OSIdleCtr;
INT32U OSIdleCtrRun;
INT32U OSIdleCtrMax;
這樣編譯器就會將這些全域變數分配在記憶體中。當編譯器處理其他.C檔案時,標頭檔變成了如下的樣子,因為OS_GLOBAL沒有定義,所以OS_EXT被定義為extern。extern INT32U OSIdleCtr;
extern INT32U OSIdleCtrRun;
extern INT32U OSIdleCtrMax;
在這種情況下,不產生記憶體配置,而任何 .C檔案都可以使用這些變數。這樣的就只需在 .H 檔案中定義一次就可以了。總結:在嵌入式c語言定義一個全域變數,而且希望此全域變數在其他c檔案中和在工程彙編中使用此變數的話。我們在標頭檔裡定義了一個全域變數,在其它檔案裡用extern 關鍵字引用即可。而如果每個檔案都引用這個標頭檔會產生重複定義全域變數的問題。我們使用這種條件編譯就能解決此問題。