この構造が他のファイルfunc.cで使用される場合はどうすればよいですか?
タイプがファイル(つまり、func.cファイル)で使用される場合、それは可視でなければなりません。最悪の方法は、必要な各ソースファイルにコピーアンドペーストすることです。
正しい方法は、それをヘッダーファイルに入れ、必要に応じてこのヘッダーファイルをインクルードすることです。
新しいヘッダーファイルを開いて構造を宣言し、そのヘッダーをfunc.cに含めますか?
これはコードが非常にモジュール化されているので、私がもっと好きなソリューションです。私はあなたの構造を次のようにコーディングします:
#ifndef SOME_HEADER_GUARD_WITH_UNIQUE_NAME
#define SOME_HEADER_GUARD_WITH_UNIQUE_NAME
struct a
{
int i;
struct b
{
int j;
}
};
#endif
この構造を使用する関数を同じヘッダーに配置します(「意味論的に」その「インターフェース」の一部である関数)。
そして通常、私は構造名にちなんでファイルに名前を付け、その名前を再び使用してヘッダーガード定義を選択できます。
構造体へのポインタを使用して関数を宣言する必要がある場合、完全な構造体定義は必要ありません。次のような単純な前方宣言:
struct a ;
十分でしょう、そしてそれはカップリングを減らします。
または、ヘッダーファイルで全体の構造を定義し、それをsource.cとfunc.cの両方に含めることができますか?
これは別の方法ですが、多少は簡単ですが、モジュール性は低くなります。機能するために構造のみを必要とする一部のコードでは、すべてのタイプを含める必要があります。
C ++では、これは興味深い複雑化につながる可能性がありますが、これはトピック外(C ++タグなし)なので、詳しく説明しません。
次に、その構造を両方のファイルでexternとして宣言する方法。?
おそらくポイントはわかりませんが、Greg Hewgillは彼の投稿で非常に良い回答をしています。Cの複数のファイルで使用されるヘッダーの構造を宣言する方法は?。
では、どのようにtypedefしますか?
- C ++を使用している場合は、使用しないでください。
- Cを使用している場合は、使用する必要があります。
C構造体の管理が面倒になる可能性がある理由は、使用するすべての場所でstructキーワードを宣言する必要があるためです。
struct MyStruct ; /* Forward declaration */
struct MyStruct
{
/* etc. */
} ;
void doSomething(struct MyStruct * p) /* parameter */
{
struct MyStruct a ; /* variable */
/* etc */
}
typedefを使用すると、structキーワードなしで記述できます。
struct MyStructTag ; /* Forward declaration */
typedef struct MyStructTag
{
/* etc. */
} MyStruct ;
void doSomething(MyStruct * p) /* parameter */
{
MyStruct a ; /* variable */
/* etc */
}
構造体の名前を維持することが重要です。書き込み:
typedef struct
{
/* etc. */
} MyStruct ;
typedefされた名前で匿名の構造体を作成するだけで、それを前方宣言することはできません。したがって、次の形式にしてください:
typedef struct MyStructTag
{
/* etc. */
} MyStruct ;
したがって、structキーワードの追加を避けたい場所ならどこでもMyStructを使用でき、typedefが機能しない場合(つまり、前方宣言)でもMyStructTagを使用できます。
編集:
Jonathan Lefflerが正当に述べたように、C99構造体宣言に関する誤った仮定を修正しました。
2018-06-01を編集:
Craig Barnesは彼のコメントの中で、明確にするために上記で行ったように、構造体の「タグ」名とその「typedef」名に別々の名前を保持する必要がないことを思い出させます。
実際、上記のコードは次のように書くこともできます。
typedef struct MyStruct
{
/* etc. */
} MyStruct ;
IIRC、これは実際にはCとの互換性を維持するために、舞台裏で、C ++がその単純な構造体宣言で行うことです。
// C++ explicit declaration by the user
struct MyStruct
{
/* etc. */
} ;
// C++ standard then implicitly adds the following line
typedef MyStruct MyStruct;
Cに戻ると、両方の使用法(別々の名前と同じ名前)を見てきましたが、私が知っている欠点はありません。そのため、同じ名前を使用すると、構造体やその他のシンボルにCの個別の「名前空間」を使用しない場合、読み取りが簡単になります。
struct b
構造体a
は未使用の型を宣言しています(おそらくk
、内側の閉じかっこの後にメンバー名を定義する必要があります。セミコロンの前