ヘッダーのstruct
sの完全な定義と単なる宣言の両方を見てきました。1つのメソッドが他のメソッドよりも優れているのでしょうか。
それが違いを生む場合、私は通常.h
でそのような構造体をtypedefします
typedef struct s s_t;
明確にするため、オプションはヘッダーファイルでの宣言とクラスでの定義、またはヘッダーファイルでの宣言と定義の両方です。どちらもリンケージによるものであっても、同じ使いやすさになるはずです。
多くの重複が見られます。 ここ しかし、完全に一致するものはありません。この点で間違っている場合は修正してください。
そのファイルのプライベート構造体は、.hの関数で使用される場合、.hファイルの宣言とともに.cファイルに入れます。
パブリック構造体は.hファイルに入れる必要があります。
どちらもリンケージによるものであっても、同じ使いやすさになるはずです。
いいえ、同じヘッダーを含む他の.cファイルを検討する場合ではありません。構造体の定義がコンパイラーに表示されない場合、その定義の詳細は使用できません。定義のない宣言(たとえばstruct s;
)を使用すると、struct s
の内部を調べようとするとコンパイラは失敗しますが、 struct s *foo;
をコンパイルします(foo
が後で参照解除されない限り)。
api.h
とapi.c
のこれらのバージョンを比較します。
Definition in header: Definition in implementation:
+---------------------------------+ +---------------------------------+
| struct s { | | struct s; |
| int internal; | | |
| int other_stuff; | | extern void |
| }; | | api_func(struct s *foo, int x); |
| | +---------------------------------+
| extern void | +---------------------------------+
| api_func(struct s *foo, int x); | | #include "api.h" |
+---------------------------------+ | |
+---------------------------------+ | struct s { |
| #include "api.h" | | int internal; |
| | | int other_stuff; |
| void | | }; |
| api_func(struct s *foo, int x) | | |
| { | | void |
| foo->internal = x; | | api_func(struct s *foo, int x) |
| } | | { |
+---------------------------------+ | foo->internal = x; |
| } |
+---------------------------------+
APIのこのクライアントは、どちらのバージョンでも機能します。
#include "api.h"
void good(struct s *foo)
{
api_func(foo, 123);
}
これは、実装の詳細を詳しく説明しています。
#include "api.h"
void bad(struct s *foo)
{
foo->internal = 123;
}
これは、「ヘッダーの定義」バージョンでは機能しますが、「実装の定義」バージョンでは機能しません。後者の場合、コンパイラーは構造のレイアウトを認識できないためです。
$ gcc -Wall -c bad.c
bad.c: In function 'bad':
bad.c:5: error: dereferencing pointer to incomplete type
$
したがって、「実装の定義」バージョンは、プライベート実装の詳細の偶発的または意図的な誤用から保護します。
構造体を他のコンパイルユニット(.cファイル)で使用する場合は、ヘッダーファイルに配置して、必要に応じてそのヘッダーファイルを含めることができるようにします。
構造体が1つのコンパイル単位(.cファイル)でのみ使用される場合、その.cファイルに配置します。
ポイントは、ヘッダーファイルに配置すると、そのヘッダーファイルを含めるだけで、複数のソースファイルの構造(またはその他の定義)を使用できるようになることです。
ただし、1つのソースファイルからのみ使用されると確信している場合は、実際には違いはありません。
オブジェクトをよりオブジェクト指向にするために、Cファイルに入れます この記事を参照 。