2016-10-13 12 views
-1

私が試したし、可能な限り次のコードを蒸留しました:これは罰金コンパイルC構造体のtypedefのと宣言原因ポインタエラー

#include <stdlib.h> 

typedef struct item{ 
    struct item *next; 
}item; 

void addItem(item *list) 
{ 
    item *newItem = list; 
    while(newItem->next != NULL){ 
     newItem = newItem->next; 
    } 

    newItem->next = malloc(sizeof(item)); 
    newItem->next->next = NULL; 
} 

int main() 
{ 
    item *groceryList = NULL; 
    groceryList = malloc(sizeof(item)); 
    if(groceryList == NULL) 
     return 1; 
    groceryList->next = NULL; 

    addItem(groceryList); 

    return 0; 
} 

。しかし、(変更の任意の組み合わせまたは)への構造体宣言を変更:

structpointertest.c:11:11: warning: assignment from incompatible pointer type structpointertest.c:15:15: error: request for member 'next' in something not a structure or union

を、私はこの問題を引き起こしている構造体宣言では理解していない:

typedef struct{ /*Removed "item"*/ 
    item *next; /*Removed "struct"*/ 
}item; 

は、コンパイル時に以下のエラーが発生します?それはネストされた構造体を使用しているという事実と関係がありますか?

ありがとうございました。

+1

コンパイラは 'item'が宣言行' item * next'にあるかどうかを知りません。 –

+0

「入れ子構造」はありません。そして、無限の再帰なしにすることはできません。 – Olaf

+0

申し訳ありませんが、私はひどく言いました。私は構造の入れ子を意味するのではなく、エイリアスの入れ子を意味しました。 –

答えて

3

Cでは、使用する前に宣言する必要があります。あなたは

typedef struct item { ... } 

を行うとstruct item部分は構造名itemが存在することをコンパイラに伝える宣言です。つまり、構造体の内部であっても、後でそれを使用してポインタを定義することができます。

あなたは構造に名前を与えていない、そしてそれは構造の内部で使用することはできませんので、型の別名itemは、構造の後を宣言されている

typedef struct { ... } item; 

を行うと。

簡単な解決策は、最初の方法を使用することです。もう1つの解決策は、構造の前に型名を宣言することです。

typedef struct item item; 
struct item 
{ 
    item *next; // Can use type-alias, as it has been declared up above 
}; 

いずれにしても、構造自体に名前を付ける必要があります。

struct item *next;(又はitem *next;)が構造体へのポインタでメンバ変数を宣言し、それ自体を再帰的にネストされた実際の構造ではないことに注意してください。まだ完全に定義されていないものへのポインタを作成することは大丈夫です。

+0

あなたの最後の段落は私の悪い言葉でした。 –

+0

ガー、サイトに新しく、コメントを入力してください!とにかくありがとうございました。私はtypedefがどのような順序で定義されているかを見ています。 –

+0

+1私はまだ完全には定義されていないものへのポインタを作成しようとしたので...そして驚くことではありません!私はそれを知らなかった – JoulinRouge