4

以前のコード ベースからいくつかの C コードに出くわし、頭を悩ませました。

コードには、次のような typedef された構造体がいたるところにあります。

typedef struct Foo {
    char *data;
    int  stuff;
} *Foo;

これは GCC で正常にコンパイルされます。

私の質問は、構造体を構造体ポインターに型定義する目的は何ですか? これは何年も前の標準的な慣習でしたか? 私が見逃しているものはありますか?構造体ポインタを難読化しているため、非常に悪いスタイルのようです。このレガシ コードを理解するための助けをいただければ幸いです。

4

3 に答える 3

7

あなたの質問が何であるかはすぐにはわかりません。特に名前が同じであることについてですか?それとも、一般的にtypedef名の後ろにポインター型を隠すことですか?

struct FooC 言語の宣言では name が導入されないため、最初の部分は実際には問題になりませんFooFooいわゆるstruct tagであり、単独では使用できません。struct Foo宣言によって導入される完全な型名は です。つまり、型の完全な名前を形成するにはとのstruct Foo両方が必要です。これを単独で使用できる短い typenameに型定義することは、広く普及しており、かなり便利な方法です。typename の綴りが struct タグの綴りと一致するという事実について、それについて何も変わったことは何もありません。たとえば、これはまったく問題ありませんstructFoostruct FooFoo

typedef struct Foo {
    char *data;
    int  stuff;
} Foo;

struct Foo f1;  /* <- declares a `struct Foo` object */
Foo f2;         /* <- also declares a `struct Foo` object */
struct Foo *f3; /* <- declares a pointer to `struct Foo` */
Foo *f4;        /* <- also declares a pointer to `struct Foo` */

typedef 名の後ろにポインター型を隠すことについては... typedef 名が struct タグと異なる場合でも、多くの人が眉をひそめている物議を醸す慣行です。私は個人的にそのようなことを避けることを好みます。また、(例のように)ポインター型を指定するために構造体タグ名と一致する型名を使用すると、さらに悪化します。本当にそうしたい場合は、次のように typedef 名に独特のスペルを付けてください。

typedef struct Foo {
    char *data;
    int  stuff;
} *FooPtr;

FooPtr f5; /* <- declares a pointer to `struct Foo` */

しかし繰り返しになりますが、新しい型名の後ろに を隠してポインター型がポインター型であるという事実を隠すこと*は、コードの可読性に悪影響を及ぼすもののように感じられます。「不透明な」型、ある種の「ハンドル」を作成する必要があり、そのポインターの性質がまったく重要ではない場合、そのようなことはうまくいくかもしれません。しかし、通常のポインターでは、そのようなことを避けるのが最善です。

于 2013-10-29T21:52:00.007 に答える
5

これは何年も前の標準的な慣習でしたか?

私が知る限りではありませんが、そのタグ名にははるかに典型的typedefでしstructたが、structポインターにはそうではありませんでした。

私が見逃しているものはありますか?structポインターを難読化しているため、非常に悪いスタイルのようです。

あなたは絶対に正しいです。typedefこのようなものは、読者を混乱させる可能性が非常に高いです。

于 2013-10-29T20:45:43.113 に答える