8

次のCコードスニペットについて考えてみます。

typedef struct node{
    int val;
    struct node* left;
    struct node* right;
}node;

void inorderTraversal(node *p){
    inorderTraversal(p->left);
    printf("%d",p->val);
    inorderTraversal(p->right);
}

typedef structの代わりにのみ書き込むtypedef struct nodeと、を呼び出すときに「互換性のないポインタ型の引数を渡す」という警告が表示inorderTraversal(root)されmain()ます。プログラムにエラーが表示されないのに、なぜこの警告が表示されるのですか?

4

3 に答える 3

11

構造体にタグ名を付けない場合は、

struct node* left;

構造体定義で、新しい(不完全な)型を宣言しstruct nodeます。したがって、aが予期されているその(不完全な)型へのポインターをnode*渡すと、互換性のない型のポインターを渡すことになります。

定義する構造体に同じ型へのポインターであるメンバーがある場合、定義でその型に名前を付けることができる必要があるため、型はスコープ内にある必要があります。

名前を付けるstructと、タイプは-その時点から-スコープ内にあり、まだ完全ではありませんが、struct node(タグがの場合node)として参照できます。typedefが完了すると、その型は、struct nodeまたはnodeのいずれかを参照できます。

ただし、タグを指定しない場合struct、typedefが完了するまでタイプは匿名であり、それ以前に参照することはできません。そして、ラインが

struct node *left;

が検出され、参照するタイプstruct nodeが不明であり、その行が新しいタイプを宣言しますが、struct nodeその何も不明です。コンパイラには、その型を現在定義されている型に接続する理由はありません。したがって、その時点で、にstructは不明な不完全な型へのポインタであるメンバーが含まれています。さて、でinorderTraversal、あなたが電話するとき

inorderTraversal(p->left);

node *pの定義によるとnode、withp->leftは、未知の不完全な型へのポインタstruct nodeです。が実際にへのポインタにpなるように作成されている場合でも、それでも動作します(ただし、異なるタイプへのポインタの表現が異なるプラットフォームを除く)が、異なるタイプへのポインタが期待される1つのタイプへのポインタを渡します。 。1つのタイプが不完全であるため、予期されるタイプと互換性がありません。p->leftnode

于 2012-10-03T13:09:17.070 に答える
0
"passing argument of incompatible pointer type"

その時点ではノードが不明であるため。そのため、新しいタイプと見なされます。

struct node{
    int val;
    struct node* left;
    struct node* right;
};

void inorderTraversal(struct node *p){
    inorderTraversal(p->left);
    printf("%d",p->val);
    inorderTraversal(p->right);
}

これで、ノードは使用する前に構造体として宣言されます。つまり struct node* left;、エラーはありません。

これも参照してください:自己参照構造体の定義?
自己へのポインタを持つC構造体

于 2012-10-03T13:10:13.703 に答える
-3

匿名を作成することはできませんtypedef。名前が必要です。structCは匿名タイプをサポートしていません。

ただし、GCC拡張機能はその機能を有効にします。-fms-extensions

于 2012-10-03T13:10:13.350 に答える