2009-07-22 18 views
48

複数のソースで使用される可能性のある変数がある場合は、ヘッダーに宣言することをお勧めしますか?またはそれを.cファイルで宣言し、他のファイルでexternを使用する方が良いですか?ヘッダーファイルの変数宣言

答えて

89

あなたはヘッダファイルに変数を宣言する必要があります:その.cファイルもヘッダーを使用する必要がありますし、標準パターンがどのように見えることをことを

extern int x; 

で定義します。ファイル:

int x; 

Cでは、定義と宣言の違いは変数のスペースを予約しているのに対し、宣言は変数をシンボルテーブルに導入するだけです(リンカが来たらリンクする時間)。

+3

**どちらも**宣言です!ファイルスコープでは、2番目の定義は(完全な)定義ではなく、_tentative定義です。 – Olaf

29

ヘッダーファイルにexternと宣言し、正確に1cファイルで定義することができます(必要があります)。

// file.h 
extern int x; // declaration 

// file.c 
#include "file.h" 
int x = 1; // definition and re-declaration 
+0

実際には、ヘッダーを常に使用する必要があります。そのため、コンパイラが宣言と定義の間で型が間違ってしまう場合に備えてください。 – caf

+0

猫、あなたは正しい、私は少し言い直します。 –

9

あなたが複数の場所に含まれるヘッダファイル内

int x; 

ようにそれを宣言する場合は、xの複数のインスタンスになってしまいます(および潜在的にコンパイルやリンクの問題)。

これにアプローチするための正しい方法は、ヘッダファイルを持つことです

extern int x; /* declared in foo.c */ 

を言った後、foo.cの中で、あなたは、あなたができるだけ多くのあなたのヘッダーファイルをインクルードすることができます

int x; /* exported in foo.h */ 

を言うことができますあなたが好きな場所。

3

キーは、ヘッダファイルとソースファイルの変数の宣言を同じに保つことです。

は私が

------sample.c------ 
#define sample_c 
#include sample.h 

(rest of sample .c) 

------sample.h------ 
#ifdef sample_c 
#define EXTERN 
#else 
#define EXTERN extern 
#endif 

EXTERN int x; 

SAMPLE.Cは一度だけコンパイルされ、このトリックを使用して、それは、変数を定義します。 sample.hを含むファイルには変数の "extern"しか与えられません。その変数にスペースを割り当てます。

xのタイプを変更すると、すべての人が変更されます。ソースファイルとヘッダーファイルで変更する必要はありません。

+2

あなたはどのように初期化に取り組んでいますか? - extern int x = 6;ほとんどのコンパイラで警告が表示されます。 – Dipstick

+0

@chrisharris - これは制限です。私は通常、変数を初期化するために各モジュールにInit()を持っています。 – Robert

+0

Cファイルのヘッダーと定義にextern宣言を置くことは、それほど面倒ではありませんか? @cafがコメントしたように、型が一致しない場合は警告が表示されます(私はすべての関数にプロトタイプが必要なので、常に対応するcファイルにヘッダーファイルを含めます)。 – Gauthier

0

このソリューションについてはどうなりますか?

#ifndef VERSION_H 
#define VERSION_H 

static const char SVER[] = "14.2.1"; 
static const char AVER[] = "1.1.0.0"; 

#else 

extern static const char SVER[]; 
extern static const char AVER[]; 

#endif /*VERSION_H */ 

私が見るのは、同じファイルに2回インクルードすると、インクルードガードで保存されないということだけです。

+1

1)#ifndefガードは、単一の*ソースファイル内で複数の定義ができないようにします(したがって、extern定義は何もしません)。 2)ヘッダー内の静的変数を宣言すると、それを含む各ソースファイルは、単一の共有変数ではなく、その変数の独自のバージョンを持ちます。技術的にはこれはリンクされますが、動作が望ましくない場合があります(この例ではconst変数を使用したように気付かないかもしれませんが、const以外のものに使用してください)。受け入れられた答えは、ほとんど常に適切な解決策です。 – Assimilater