2009-04-01 21 views
0

私は、ワークスペースに* .cと* .hファイルを持つプレーンなCコードを持っています。
私はヘッダファイルのインクルードはどのように行われますか?

struct my1 
{ 
int a; 
.. 
.. 
}my_t; 

として、いくつかの構造を宣言する1.Hヘッダファイルを持っているが、私は次のように別のヘッダファイル2.Hにタイプstruct MY1の変数を宣言しようとすると、: -

struct my1 variable1; 

この宣言ポイントでエラーが発生します。

my1が2.hファイルでここで定義されていないように見えます。

ファイル1.hでは2.hを含める必要があります。ファイル2.hでは、再帰的なインクルードを恐れて1.hを含めることはできません。

私の質問は: -

  1. 何私はこの場合、コンパイルエラーを解決するために宣言する必要がありますか?

    このすべてのことで、ヘッダーファイルのインクルードについてさらに質問がありました。

  2. どのようにヘッダファイルがどのように順番にどのヘッダファイルに含まれますか?

  3. ヘッダーファイルを再帰的にインクルードすると、他のファイルやその他のファイルを最初から含むエラーが発生しますか?質問はややいくつかの読みやすさの問題を提起する場合

はとても申し訳ありませんが、いくつかのセキュリティ上の理由で実際のコードスニペットを投稿できませんでした。

答えて

0

私はCと仕事をしてからしばらくしていますが、あなたがしたいことはforward my1を定義することだと思います。

2.Hでは、上部付近にこれを入れてみてください:

struct my1; 

申し訳ありませんが、私はあなたの他の二つの質問に答えることはできません。

+0

あなただけのことを行う必要がありますそのフィールドにはアクセスできません)。 –

4

あなたはすべてのあなたの.hファイル(これはinclude guardと呼ばれている)に含めるロックを入れて起動する必要があります:あなたはそれを複数回含めることができ

#ifndef ONE_H 
#define ONE_H 

//rest of header 

#endif //ONE_H 

その方法。

第二:

typedef struct my1 { int a; .. .. }my_t; 

あなたは(ないC++での)Cでのtypedefが必要

ヘッダが含まの順に含まれています。

あなたは、で始まるファイルabc.cコンパイルする場合:a.hが最初に含まれます、その後

#include "a.h" 
#include "b.h" 

、その後、B。H.を

コードをファイルに貼り付けるかのように考えることができます。それはその時点で含まれています。

+0

@Burkhard:もしa.hが内部的にいくつかのc.hを含んでいれば、それは最初にインクルードされ、次にb.hは正しいでしょうか? – goldenmean

+0

そして、あなたは#ifndefの権利を意味しますか? – goldenmean

+0

typedefは必要ありません。新しい名前を使用することができるので、宣言で構造体を使用するだけで簡単に使用できます。 – Eddie

0
// Header1.h 
typedef struct tagHeader1 
{ 
} Header1; 

// Header2.h 

struct Header1; 

// Header2.c 

#include "Header1.h" 

注:これはポインタ(およびC++参照)でのみ機能します。完全なオブジェクトへの参照がある場合、コンパイラはそれについて知る必要があります。

1

ヘッダーファイルはの順に含まれ、ディレクティブが含まれています。コンパイラでディレクティブが含まれていれば、それを含むファイルを開き、すべての内容をインクルードファイルに挿入するだけです。

含まれているファイルにが含まれていて、内部にディレクティブが含まれている場合、同じことが行われます。このプロセスは、のすべてにディレクティブが処理されるまで続きます。

その後、コンパイルが開始されます。

これは、ファイルが複数回含まれている(AとBが含まれていて、BとCの両方にDが含まれている)場合、コンパイラは再定義について不平を言うことがよくあります。この問題を解決するには、包含ロック(別名はガードを含む) - ifdefディレクティブを追加します。

//file Header1 
#ifndef Header1Guard 
    #define Header1Guard 
// all the header text here 
#endif 
+0

しかし、さまざまなヘッダファイルを含む複数のソースファイルがある場合、どのソースファイルからヘッダファイルのインクルードが開始されますか? – goldenmean

+0

これは通常、コンパイラによって異なります。ディレクトリ内のファイルのリストを取得し、その順序に従うか、プロジェクトで指定された順序を使用するか、またはファイルを作成するだけです。 – sharptooth

+0

とにかく、各ソースファイルは別々にコンパイルされ、この順序は組み込みプロセスには影響しません。 – sharptooth

1

私はガードの提案を2回続けます。

#ifndef HELLOWORLD_H_ 
#define HELLOWORLD_H_ 

// Header stuff here. 

#endif // HELLOWORLD_H_ 

コンパイラがする#includeだ参照

が、それは単にヘッダファイルの内容(マイナスヘッダー内の任意の処理されたディレクティブ)とその行を置き換えます。

は、私は宗教的に次のヘッダーテンプレートを使用します。したがって、再帰的なインクルードを危険にさらすことなく、好きなだけ多くの場所にファイルを含めることができます。

1

すべてのヘッダーファイルは、includeディレクティブがあるすべての変換単位(ソースファイル)に含まれています。これは意図的なものであり、インクルージョンガードでも発生します。構造体を使用するすべての翻訳単位は、その構造体がどのように定義されているかを知っている必要があり、アプリケーションのすべての翻訳単位で同じ方法でメモリにレイアウトできます。封入警備員は、それが複数回に1回の翻訳単位内にが含まれるのを防ぐだけです。インクルードファイルは、その翻訳単位内にインクルードした順にインクルードされます(インクルードファイルには他のファイルが含まれていると再帰的にインクルードされます)。コンパイルされる翻訳単位の順序は、あなた(またはあなたのIDE)がコンパイラに指定するまでです。しかし、すべての翻訳単位がビルドプロセスのリンクフェーズに達するまで完全に独立しているので、その順序は何であってもかまいません。

2

これは前に言われた人々のようです。

私はちょうど#ifdefがあなたを助けないことさえあることを付け加えたいと思います。

//file1.h 
#ifndef F1 
#define F1 

#include "file2.h" 

struct file1st { 
    struct file2st *ptr; 
}; 

#endif 

//file2.h 

#ifndef F2 
#define F2 

#include "file1.h" 

struct file2st { 
    struct file1st *ptr; 
}; 

#endif 

//main.c 

#include "file1.h" 
#include "file2.h" 

/* 
This will give you an error of **struct file1st not defined** 
Let's see why: 

1) file1.h is included 
2) file1.h includes file2.h before it declares anything 
3) the definition of struct file2st occurs and it uses struct file1st which isn't declared yet 
*/ 

int main(int argc, char* argv[]){ 
    struct file1st st1; 
    struct file2st st2; 

    return 0; 
} 

これを動作させる方法がある:あなたがヘッダーファイルをインクルードしたくないとあなただけのポインタ(ドンで構造体を参照する場合

//file1.h 
    #ifndef F1 
    #define F1 

    struct file2st;//just declare, it will be defined later. 

    struct file1st { 
     struct file2st *ptr; // ok, compiler KNOWS the size of struct file2st*(pointer) 
     struct file2st file2Var;// NOT ok, compiler doesn't know sizeof(struct file2st) 
    }; 

    #endif 

    //file2.h 

    #ifndef F2 
    #define F2 

    #include "file1.h" 

    struct file2st { 
     struct file1st *ptr; 
    }; 

    #endif 
+0

あなたは#ifdefを持っています。#ifndefは数回あるはずです... – RBerteig

関連する問題