2017-01-09 8 views
0

以下のコードはvtableを実装するためのコードです。私はA関数ポインタのC構文の理解

typedef struct A{ 
     int a; 
     A_functable *vmt; 
    } A; 

方法であるA_functableのメンバーであるvoid (*A)(struct A*);で関数ポインタとして(*A)に言及理解できませんでした

struct A; 

typedef struct { 
    void (*A)(struct A*); 
    void (*update)(struct A*); 
    int (*access)(struct A*); 
} A_functable; 

typedef struct A{ 
    int a; 
    A_functable *vmt; 
} A; 

次のコードで

、この構文を理解するには?

void (*A)(struct A*); 

+2

他の2つの関数ポインタを読み込むのと同じように、ちょうど 'A'という名前です。 – user2357112

+4

'A_functable'の' A'は、後で紹介するタイプ名 'A'とは完全に別です。混乱を避けるために、著者は別の名前を使用していたはずです –

+0

おそらくテスト/宿題の質問... – Rafael

答えて

2

ことのみ以下にさらに定義されるように、第1 Atypedef struct A { ... } Aを参照していません。この時点で、コンパイラはAという型について何も知らない。 Aは単にstructメンバーの名前です。ちょうどupdateaccessのようになります。

struct Aしかし、構造体を参照してくださいん。struct A;宣言がさらにアップあります)

0

彼らは異なる名前空間です。 Cにおいて

四つの異なる名前空間が構造体/共用体/列挙するため

  • タグ構造体/共用の
  • メンバー(実際には別の名前空間は、各構造体/共用体に割り当てられている)
  • ラベルあります
  • 通常の識別子。異なる名前空間の

(C90のセクション6.1.2.3)

識別子は他のものと衝突せず、別々のエンティティとして呼ばれます。

だから、あなたの場合には、構造の

  • メンバー、(*A)が関数ポインタであることは、第二の名前空間にあります。
  • struct typedef struct Aのタグは、最初の名前空間にあります。
  • 通常の識別子であるstruct型は、4番目の名前空間にあります。
  • さらに、関数ポインタ(*A)(struct A*)の関数型は、通常の型である4番目の名前空間にあります。
+0

「オブジェクト」は、識別子ではなく記憶領域を意味します。一部のオブジェクトには識別子が関連付けられています –