2012-04-03 207 views
0

對不起,這是一個基本的問題,但我所有的研究只是勉強錯過回答我的問題,我只是想仔細檢查之前,我寫我有一個假設所有代碼。 我使用C和我有聲明一些變量,一個頭文件(int S,char陣列,int陣列)。如果我有一個使用這些全局變量的函數,我假設我可以在不傳遞它們的情況下使用這些變量?全局變量和函數

例 頭文件:

int state; 
int lnArray[]; 

C文件:

void function(){ 
    int i; 
    for(i=0;i<5;i++;){ 
     if(lnArray[i]<10)  
     state = lnArray[i]; 
    } 
} 

回答

3

這是正確的。這就是爲什麼他們被稱爲「全局」變量:他們在任何範圍內都可用。

+0

好的。謝謝。在我需要重寫代碼或發生大量錯誤之前,我只是想確定一下。 – Sams 2012-04-03 03:46:27

+2

現在你知道它們是什麼了,明智地使用它們。不要僅僅爲了避免傳遞參數而使用它們。在有全局數據的情況下有意義使用它們(即需要一個實例並在很多地方引用)。全球數據存在*許多*下行風險。小心踩踏。 – 2012-04-03 03:56:59

+2

但是,您不僅在頭文件中聲明瞭變量,還定義了它們。你不應該這樣做:如果有幾個模塊使用相同的hader,你會得到名稱衝突。 – Matthias 2012-04-03 03:57:08

1

你必須要小心這裏。 「環球」變量是那些可在代碼中的任何一點,但有全球標準沒有正式定義 - 它使用類似範圍,存儲時間和聯動較正式用詞。全球的

一個定義適用於單個文件,另一個可以跨多個文件應用。

隨着您的特定設置,如果您在多個C源文件的頭文件,然後試圖將它們鏈接在一起,你會得到鏈接錯誤,因爲每個對象文件具有變量的自己副本,他們「再所有試圖以出口爲主。

如果你希望你的變量是全球性的一個源文件,把它們在該源文件的頂部,並使其靜態(有效看不見的鏈接):

static int state; 

這意味着每一個功能在那個文件可以得到他們,但他們不會干擾其他文件。

但是,如果你希望你的變量是在所有的源文件全球,放在一個頭文件中的聲明在一個C源文件定義。一個聲明宣稱,雖然定義帶來了它進入存在的東西存在:

something.h: 
    extern int state;      // declare it 

file1.c: 
    #include "something.h"    // declare it (in header) 
    int state;       // AND define it. 
    // Now you can use state anywhere. 

file2.c: 
    #include "something.h"    // declare it (in header) 
    // Now you can use state anywhere. 

這意味着有一個state的所有文件訪問副本。


就使用全局變量而言,通常應儘可能地避免。使用它們會使封裝變得更加困難,並使代碼的內部暴露於外部。

基本規則是使用盡可能小的範圍爲任何單個項目,仍然允許您達到目的。有時候,這意味着要傳遞信息。

如果你真的不想傳遞它們,至少要將所有數據和操作它的代碼隔離到一個文件中,以便你可以將它隱藏起來。

6

請注意,您所寫的頭文件定義了全局變量state(它聲明瞭一個不完整的數組lnArray);它應該只是宣佈他們:

extern int state; 
extern int lnArray[]; 

然後,在源文件中的一個(源文件,該文件還包括頭),你寫的:

int state = 0; 
int lnArray[XXX]; // XXX is an enum or #define that gives the array size 

或者你可以有lnArray一個初始化這給出了數組的大小。

如果你的編譯器使用'通用定義'機制,你可能會逃脫你得到的東西;很多人做但是添加一個初始化程序,你就會崩潰。

參見:What are extern variables in C?

注意,全局變量通常不是一個好主意;很難跟蹤哪些代碼正在訪問並修改它們。人們竭盡全力避免全局變量。全局常量是另一回事;他們提出的問題較少,儘管你仍然不願意使用它們。

2

您提供的示例是正確的,但很容易出現「重新聲明」鏈接器錯誤。

使用全局變量的首選方法是:


/* example.h */ 
extern int state; 
extern int lnArray[]; 

/* example.c */ 
int state; 
int lnArray[SOME_SIZE_HERE]; 

通過你能夠#include <example.h>儘可能多的時間,因爲你喜歡的頭文件聲明extern S,從不同的源文件只要你喜歡,沒有statelnArray被重新聲明。