全域性變數巨集定義 精

2023-02-10 19:24:06 字數 3041 閱讀 3660

以下是如何定義全域性變數。眾所周知,全域性變數應該是得到記憶體分配且可以被其他模組通過c語言中extern關鍵字呼叫的變數。因此,必須在 .

c 和 .h 檔案中定義。這種重複的定義很容易導致錯誤。

error[e46]: undefined external "serbfr" referred in zlg522s d:\mcu\430prj\zlg522s\debug\obj\ )

以下討論的方法只需用在標頭檔案中定義一次。雖然有點不易懂,但使用者一旦掌握,使用起來卻很靈活。表1.2中的定義出現在定義所有全域性變數的.h標頭檔案中。

.h 檔案中每個全域性變數都加上了***_ext的字首。***代表模組的名字。該模組的.c檔案中有以下定義:

當編譯器處理.c檔案時,它強制***_ext(在相應.**件中可以找到)為空,(因為***_globals已經定義)。

所以編譯器給每個全域性變數分配記憶體空間,而當編譯器處理其他.c檔案時,***_global沒有定義,***_ext被定義為extern,這樣使用者就可以呼叫外部全域性變數。

為了說明這個概念,可以參見uc/os_其中包括以下定義:

同時,ucos_有中以下定義:

當編譯器處理ucos_時,它使得標頭檔案變成如下所示,因為os_ext被設定為空。

這樣編譯器就會將這些全域性變數分配在記憶體中。當編譯器處理其他.c檔案時,標頭檔案變成了如下的樣子,因為os_global沒有定義,所以os_ext被定義為extern。

在這種情況下,不產生記憶體分配,而任何 .c檔案都可以使用這些變數。這樣的就只需在 .h 檔案中定義一次就可以了。

【網友經驗(來自csdn)】:儘管乙個全域性變數或函式可以(在多個編譯單元中) 有多處「宣告」, 但是「定義」 卻只能允許出現一次。定義是分配空間並賦初值(如果有) 的宣告。

最好的安排是在某個相關的.c 檔案中定義, 然後在標頭檔案(.h) 中進行外部宣告, 在需要使用的時候, 只要包含對應的標頭檔案即可。

定義變數的.c 檔案也應該包含該標頭檔案, 以便編譯器檢查定義和宣告的一致性。

這條規則提供了高度的可移植性: 它和ansi c標準一致, 同時也相容大多數ansi 前的編譯器和聯結器。unix 編譯器和聯結器通常使用「通用模式」允許多重定義, 只要保證最多對一處進行初始化就可以了; ansi c 標準稱這種行為為「公共擴充套件」, 沒有語帶雙關的意思。

如果希望讓編譯器檢查宣告的一致性, 一定要把全域性宣告放到標頭檔案中。特別是, 永遠不要把外部函式的原型放到.c 檔案中:

通常它與定義的一致性不能得到檢查, 而矛盾的原型比不用還糟糕。

如何定義巨集、取消巨集

//定義巨集

#define [macronamemacrovalue]

//取消巨集

#undef [macroname]

普通巨集#define pi (3.1415926)

帶引數的巨集

#define max(a,b) ((a)> (b)? (a),(b))

關鍵是十分容易產生錯誤,包括機器和人理解上的差異等等。所以如果用的話,建議所有的層次都要加括號。

條件編譯

#ifdef ***…(#else) …#endif

例如 #ifdef dv22_aux_input

#define aux_mode 3

#else

#define auy_mode 3

#endif

#ifndef *** … (#else) … #endif

標頭檔案(.h)可以被標頭檔案或c檔案包含;

重複包含(重複定義)

由於標頭檔案包含可以巢狀,那麼c檔案就有可能包含多次同乙個標頭檔案,就可能出現重複定義的問題的。

通過條件編譯開關來避免重複包含(重複定義)

例如 #ifndef __headerfile***__

#define __headerfile***__

…檔案內容

#endif

#define的一些用法

karla 發表於 2005-3-28 16:36:00

1.簡單的define定義

#define max 1000

乙個簡單的max就定義好了,它代表1000,如果在程式裡面寫

for(i=0;i

編譯器在處理這個**之前會對max進行處理替換為1000。

的「函式定義」

define可以像函式那樣接受一些引數,如下

#define max(x,y) (x)> (y)?(x):(y);

這個定義就將返回兩個數中較大的那個,看到了嗎?因為這個「函式」沒有型別檢查,就好像乙個函式模板似的,當然,它絕對沒有模板那麼安全就是了。可以作為乙個簡單的模板來使用而已。

但是這樣做的話存在隱患,例子如下:

#define add(a,b) a+b;

在一般使用的時候是沒有問題的,但是如果遇到如:c * add(a,b) * d的時候就會出現問題,代數式的本意是a+b然後去和c,d相乘,但是因為使用了define(它只是乙個簡單的替換),所以式子實際上變成了

c*a + b*d

另外舉乙個例子:

#define pin (int*);

pin a,b;

本意是a和b都是int型指標,但是實際上變成int* a,b;

a是int型指標,而b是int型變數。

這是應該使用typedef來代替define,這樣a和b就都是int型指標了。

3.巨集的單行定義

#define a(x) t_##x

#define b(x) #@x

#define c(x) #x

我們假設:x=1,則有:

a(1)------〉t_1

b(11 '

c(11 "

的多行定義

define可以替代多行的**,例如mfc中的巨集定義(非常的經典,雖然讓人看了噁心)

#define macro(arg1, arg2) do while(0) /* (no trailing

關鍵是要在每乙個換行的時候加上乙個 "\ "

關於全域性變數的定義

在用vb開發軟體時,經常需要在不同的窗體間共享資料,但在過多的使用全域性變數時不便於軟體的除錯和修改。通常有兩種解決方法。第一種方法 定義全域性變數,然後在各個窗體中直接使用,例如 public strcustomerid as string public strcustomername as st...

全域性變數 區域性變數 靜態全域性變數 靜態區域性變數的區別

118848 0500 20 0other 15 013 868 00 0星級blog 0gyan ffffff 187218 no repeat blank 144143 02010 09 13 21 33 41 144141 02010 09 13 21 33 31 20100913 20100...

C中怎樣定義和宣告全域性變數和函式最好

首先,儘管乙個全域性變數或函式可以 在多個編譯單元中 有多處 宣告 但是 定義 卻只能允許出現一次。定義是分配空間並賦初值 如果有 的宣告。最好的安排是在某個相關的.c 檔案中定義,然後在標頭檔案 h 中進行外部宣告,在需要使用的時候,只要包含對應的標頭檔案即可。定義變數的.c 檔案也應該包含該標頭...