2011-12-20 3 views
2

Мне сложно понять typedefs в этой структуре C.typedef путаница в C

typedef struct node { 
    int value; 
    list rest; 
} node; 

typedef struct node *list; 

В чем разница между объявлением typedef «node» и «списком»? Почему список предваряется указателем? Не является также и «узлом» указателя? Почему я не могу просто сказать «typedef struct node list» и опустить звездочку? Я искал везде, и я не могу найти удовлетворительного ответа.

ответ

1

node не является указателем; это struct. list - это typedef для указателя на node.

Вы typedef a struct в C, чтобы избежать ввода struct node ... везде.

Является ли это хорошей практикой, является сомнительным (большинство соглашается с тем, что скрытие типа указателя за typedef, если оно действительно непрозрачно, является плохой идеей), но это его суть.

1

В первой декларации говорится, что структура node является структурой. Второй говорит, что list является указателем на узел.

Таким образом, это будет правильный код, используя эти заявления:

list x; 
node n; 

x = &n; 

объявляя элемент с помощью typedef struct node list не является правильным. Оператор typedef объявляет новый тип. Ключевое слово typedef не является частью имени типа.

0

node просто синоним для struct node

list является указатель к struct node (или node)

Каждый экземпляр узла содержит list указатель, который позволяет создавать структуры данных, такие как (отдельно) linked lists и т. д.

1

node является struct, который (смущающе) назван так же, как struct node. list является указателем на struct node. Таким образом, следующие условия эквивалентны:

struct node *a; 
node *a; 
list a; 
+0

Ничего себе, вы, ребята, потрясающие! Огромное спасибо!! – wandergeek

5

Первый typedef определяет node как псевдоним для struct node, чтобы позволить вам обращаться к нему просто как node без написания struct node каждый раз (в С «обычных» имена типов и struct имен живут в двух разных пространствах имен). Это эквивалентно:

struct node 
{ 
    int value; 
    struct node* rest; 
}; 

typedef struct node  node; 

Второй typedef, вместо этого, определяет list в качестве псевдонима для node *, т.е. определяет тип list, как указатель к node структуре.

(кстати, лично я нахожу, что это очень плохой стиль: скрывающие указатели внутри typedef s почти всегда плохая идея, можно утверждать, что указатель на первый элемент в списке можно было бы назвать списком , но использование list даже для указателя rest IMHO не очень приятно)

+1

Я лично не согласен с последней частью. Представленная структура данных представляет собой односвязный список. Набрав его как «просто», указатель узла затушевывает фактическое намерение. – Chuck

+1

Ну, я согласен с последней частью, поскольку мне действительно приходилось работать с такой бессмыслицей 'typedef'. –

+1

@Chuck: как я уже сказал, я могу понять это использование, но я бы использовал его, чтобы указать на голову списка, а не на каждый «следующий» указатель. Или, что еще лучше, я бы определил отдельный 'struct list {struct node * head; } ', чтобы сохранить тип' list', отличный от того, чтобы быть «просто» «узлом struct» * –