可以說我在main.c中有一些全局變量GLOBAL,但是我的main.c有一個#include「other.h」。但other.h也有全局變量GLOBAL。如何在C中訪問正確的全局變量?
當我在main中編寫GLOBAL時,如何讓編譯器知道我的意思。有沒有可以使用的「this」關鍵字?
可以說我在main.c中有一些全局變量GLOBAL,但是我的main.c有一個#include「other.h」。但other.h也有全局變量GLOBAL。如何在C中訪問正確的全局變量?
當我在main中編寫GLOBAL時,如何讓編譯器知道我的意思。有沒有可以使用的「this」關鍵字?
我假設你已經在程序中定義了變量,而不是在使用#define的預處理器中。
如果要引用在main.c中創建的那個,只需鍵入global。要引用頭文件中的內容,請使用關鍵字extern。
儘管說實話,你最好將它們聲明爲兩個獨立的變量名。
我很抱歉,但這並沒有對我產生任何意義。特別是建議使用'extern'來引用「頭文件中的變量」(???) – AnT 2010-01-15 02:50:00
「關鍵字extern表示變量的實際存儲和初始值存儲在其他地方」我一直使用C語言完成全局變量,就像我想引用頭中定義的全局變量一樣,它聲明爲 extern
在C程序中不能有兩個具有相同名稱的全局變量。 C可能允許通過規定的規則在同一文件範圍內有多個定義,但無論如何所有定義都將引用相同的變量。所以,顯然你的問題是基於不正確的前提。這裏沒有「哪一個」的問題。您只有一個變量。
例如,你可以有文件範圍的定義的序列用C翻譯單元
int i;
int i;
int i;
這是合法的用C(相對於C++),並且所有這些定義實際定義相同的變量,不是三個不同的變量。當然,如果其中一個變量被定義爲局部變量(如果是這樣,你必須在你的問題中說明它)(順便說一句,爲什麼它叫GLOBAL
呢?),那麼它會隱藏名稱在文件範圍(或任何更高範圍)中定義的變量。在這種情況下,無法訪問C中的隱藏名稱。重命名局部變量以避免隱藏全局變量。
「other.h也有變量」的意思不清楚。在這種情況下,「有」意味着什麼?變量在其他.h中定義了?或者只是宣稱?如果它只是被宣佈,那麼它並不真正「擁有」它。如果是定義爲那麼......那麼真正的問題是:爲什麼要在.h文件中定義變量?
GLOBAL是兩個文件中的全局變量,而不是本地變量 – SuperString 2010-01-15 02:23:11
我知道。我的答案中的95%專注於兩種聲明都是* global *的情況。提到一個地方聲明是作爲一個附註。 – AnT 2010-01-15 02:26:14
Andrey,有一種方法可以訪問局部變量(比如說函數作用域) - 在更小的範圍內將其重新聲明爲'extern' – qrdl 2010-01-15 05:50:00
每個對象模塊只能有一個定義。第二個,如果具有相同的內容,將被忽略。如果不同,則會導致編譯器錯誤。
從技術上講,該標準需要一個定義。由於Fortran COMMON的定義,附錄J確實認可了這個標準的一個「共同擴展」,這是一個可怕的雙關(或者至少是雙關係)。 – 2010-01-15 01:37:07
這可能不是您正在尋找的答案,但您爲什麼不嘗試首先避免這種情況(以及可能(全部)使用全局變量)?
首先,如果這首先是個問題,那麼您使用的是糟糕的庫,如果可能的話應該重寫/切換。如果你不能,你可以做這樣的事情:
other.h:
int GLOBAL;
//...other stuff
爲主。ç
int GLOBAL;
#define GLOBAL OTHER_GLOBAL
#include "other.h"
#undef GLOBAL
int main(int argc,char** argv)
{
printf("%i %i",GLOBAL,OTHER_GLOBAL);
getchar();
return 0;
}
但是,如果作爲首都暗示,GLOBAL
是#define
版,這可能無法正常工作。 (但它是值得一試無妨。)
只要將main.c中的'GLOBAL'重命名爲'MY_GLOBAL'或類似的名稱會更容易和更安全?不需要毛茸茸的宏。 – 2010-01-15 03:01:50
你實際上並不有兩個變量。只有一個,如果兩個模塊使用相同的名稱聲明相同的全局變量,您將得到編譯器(或鏈接器)錯誤,或者編譯器/鏈接器將決定您是否意味着這是單個變量的冗餘聲明併合並它們。
像其他人所說的,避免使用同一個全局變量/函數名。養成用模塊名稱加前綴的習慣。即MODULE1_state,MODULE2_state等
如果一個全局變量,只是要一個源文件內使用,不匹配的頭文件中聲明。請將其聲明在源文件的頂部,並使用static
關鍵字。需要使用其他模塊訪問的變量需要使用extern
關鍵字在頭文件中聲明。全局功能也是如此。它有助於保持相同的公共/私人紀律你會像C++,Java和C#的面向對象的語言正常使用等
例子:
module.h中中:
#ifndef MODULE_H /* Header guard */
#define MODULE_H
/* Declarations for entities that CAN be accessed by other modules,
i.e. "public". */
extern int MOD_publicVariable;
extern void MOD_publicFunction(int arg);
#endif // MODULE_H
在的module.c:
/* Definitions for entities that CAN be accessed by other modules,
i.e. "public". */
int MOD_publicVariable = 42;
void MOD_publicFunction(int arg) {...}
/* Declarations for entities that CAN'T be accessed by other modules,
i.e. "private". */
static double MOD_privateVariable = 12.34;
static void MOD_privateFunction1(void);
static void MOD_privateFunction2(void);
/* Function definitions. */
void MOD_privateFunction1(void) {
int localVariable; /* This doesn't need the module prefix. */
....
}
void MOD_privateFunction2(void) {
....
}
模塊前綴(mod_個)可以直接在模塊的名字命名,也可以使用的縮寫。試驗,你最終會選擇一個你喜歡的會議。始終如此使用前綴模仿OO語言中的類/模塊/名稱空間的概念。
確保你知道與定義聲明之間的區別,和extern與靜態。
這惹惱我,C語言課本和課程忽略或掩蓋了多模塊編程的藝術。
編輯: 我忘了提,你不應該讓一般全局變量提供給其他模塊(即讓他們的「私人」)。如果其他模塊需要訪問該變量,請提供「public」「setter」和/或「getter」函數。
我喜歡你強調頭部中的*聲明*,它只是說這個名字的變量存在,而它的*定義*在module.c中,它實際上爲它分配空間(而哪一個容易混淆的是也是一個聲明)。我認爲這是OP正在絆倒的幾件事情之一。 – 2010-01-15 03:07:17
變量未在頭文件中定義的一個很好的例子。 :-) – 2010-01-15 01:55:58
你應該總是在.c文件中定義*全局變量(這爲它們分配空間),*在.h文件中使用'extern'聲明它們(這使得它們對其他模塊可見)。 – 2010-01-15 03:09:07