2014-09-12 2 views
3

Действующая декларация.Декларация самоотводящей структуры

struct node 
{ 
    int a; 
    struct node *next; 
}; 

Однако, когда мы определяем следующее, оно дает ошибку.

"error: field ‘next’ has incomplete type" 

Почему это так?

struct node 
{ 
    int a; 
    struct node next; /* Not a pointer */ 
}; 
+0

Да, я исправился, что –

ответ

2

узел struct node является «STRUCT тег», который в точке вы пишете это создает «неполный тип»: структурная переменная, которая в данный момент не объявлена, но не определена.Тип не завершен до окончательного }; вашей структуры.

В C неполный тип можно ссылаться даже до того, как он будет полностью определен, указав на этот тип указатель. Однако вы не можете назначить переменную (экземпляр) этого типа, потому что фактическое определение структуры еще не определено. (Это работает точно так же, как абстрактные базовые классы в C++, если вы знакомы с теми.)

Так что, когда вы пишете

struct node { 
    int a; 
    struct node *next; 
}; 

строка struct node *next означает «здесь является указателем на узел структуры, несмотря на то, Я понятия не имею, как этот тип определен еще ». Но вы не можете объявить переменную типа struct node внутри определения структуры этого же типа, просто потому, что вы не можете использовать что-то, прежде чем вы ее создали.

0

это должно быть так:

struct node { 
    int a; 
    struct node *next; 
}; 

это работает,

но

struct node { 
    int a; 
    struct node next; 
}; 

не может быть понят компилятором, как node становится рекурсивной структурой, и компилятор не знает, сколько памяти выделяется для node.

Однако, если вы используете указатель, он понимает, что размер указателя равен размеру памяти, подлежащей адресу, и, следовательно, сохраняет это пространство независимо от того, является ли node полной структурой.

1

Ваше второе объявление будет определять структуру, которая бесконечно глубоко вложенна, что невозможно.

+0

На самом деле, мой вопрос в том, есть ли ошибка в объявлении типа указателя, почему ошибка при объявлении структуры? –

+0

Первое объявление действительно, поскольку указатель имеет постоянный размер независимо от указанной структуры. С другой стороны, невозможно построить структуру, вложенную в себя, поскольку результирующая структура будет иметь бесконечный размер. – Codor

2

Вы не можете иметь структуру, которая содержит себя в качестве члена:

struct node 
{ 
    int a; 
    struct node next; 
}; 

Думай об этом вопросе: если это возможно, что размер такой структуры? struct node содержит struct node next в качестве члена, то член next будет содержать элемент типа struct node, и так далее, и так далее, и так далее ... Размер был бы бесконечным.

0

Адрес указателя магазина, структура имеет структуру. Если бы объявленная структура была бы рекурсивной и бесконечной. Если объявленный как указатель, он ссылается на другую структуру где-то в другом месте.

0

Бесконечные узлы внутри узла? Имеет ли это смысл? Каким будет размер «узла структуры»?

1

Это тот же случай, как с упреждающим объявлением типа класса/структурами:

struct node; 

struct node* node_ptr; /* is valid */ 
struct node node_instance; /* is invalid */ 

Так struct node; в основном говорит: эй есть структура, определенная где-то за пределами этого файла. Тип действителен, указатели могут использоваться, но вы не можете создать экземпляр объекта.

Это связано с тем, что размер указателя известен и специфичен для целевой архитектуры (например, 32 или 64-разрядной). Размер структуры неизвестен до объявления.

При объявлении типа completey, то вам будет позволено объявить объект этого типа:

struct node { 
    int a; 
    struct node* b; /* this will work, but the size of struct is unknown yet */ 
} 

struct node* node_ptr; /* this works always with full and forward declarations */ 
struct node node_object; /* now, the size of struct is known, so the instance may be created */