2012-04-03 13 views
0

申し訳ありませんが、これは基本的な質問ですが、私のすべての研究はちょっと質問に答えることがほとんど見当たりませんでした。 私はCを使用しており、いくつかの変数(ints、charアレイ、intアレイ)を宣言したヘッダーファイルがあります。これらのグローバル変数を使用する関数がある場合、変数を渡さずに変数を使用できると仮定していますか?C言語の変数と関数

例 ヘッダファイル:

int state; 
int lnArray[]; 

CのFILE:

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

答えて

3

正しいです。それが「グローバル」変数と呼ばれる理由です。これらはすべてのスコープで利用できます。

+0

大丈夫です。ありがとうございました。私は、コードを書き直す必要があったり、エラーが多かったりする前に確かめたいと思っていました。 – Sams

+2

あなたは彼らが何であるかを知ったので、賢明に使いましょう。パラメーターを渡すのを避けるためにそれらを使用しないでください。グローバルデータを持つことが理にかなっている場合(つまり、あるインスタンスを必要とし、多くの場所で参照されている場合)、それらを使用します。グローバルデータには、多くの*下振れリスクがあります。慎重に踏んでください。 –

+2

しかし、ヘッダー内の変数を宣言しただけでなく、*定義した*もあります。あなたはそうしてはいけません:いくつかのモジュールが同じ名前を使用している場合、名前の競合が発生します。 – Matthias

1

。 「グローバル」変数とは、コード内の任意のポイントで使用可能な変数ですが、標準でグローバルの正式な定義はありません。スコープ、格納期間、リンケージなどのより正式な用語を使用します。

グローバルの定義は1つのファイルに適用され、別のものは複数のファイルに適用されます。

複数のCソースファイルにそのヘッダーファイルを含めてそれらをリンクしてみると、各オブジェクトファイルに自身のの変数のコピーがあり、リンクエラーが発生します。 すべてエクスポートしようとしています。

あなたの変数は、単一のソースファイルのグローバルもそのソースファイルの先頭にそれらを入れて、(リンカを効果的に見えない)、それらを静的にしたい場合:

static int state; 

これは、すべての機能を意味し、そのファイルにはまだアクセスできますが、他のファイルに干渉することはありません。あなたの変数はすべてのソースファイル間でグローバルになりたい場合は

しかし、ヘッダファイル内宣言と1つの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のコピーがあることを意味します。


グローバル変数を使用するという点では、できるだけ避けるべきです。それらを使用するとカプセル化がはるかに難しくなり、コードの内部が外部からの操作にさらされます。

基本的なルールは、個々のアイテムに可能な限り小さな範囲を使用することです。これにより、あなたはあなたの目的を達成することができます。そして時々、物事を回すことを意味します。

本当にそれらを渡したくないのであれば、少なくともそれを隠すことができるように、すべてのデータとそれを操作するコードを1つのファイルに分離してください。

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

あなたが指定した例は正しいものの、「再宣言」リンカーエラーが発生する可能性があります。

グローバル変数を使用する好ましい方法は次のとおりです。できるだけ多くの異なるソースから、好きなようにあなたが#include <example.h>など、多くの時間をことができるしているヘッダファイルにextern Sを宣言することで


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

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

stateまたはlnArrayを再宣言することなく、好きなようにファイルを作成できます。