2015-05-01 4 views
1

Эта ошибка кажется очень простой в устранении, но я пытался и не имел понятия.C: Неполное определение типа struct

Так у меня есть три файла:

symtable.h:

typedef struct symbolTable *SymTable_T; 

symtablelist.c:

#include "symtable.h" 

struct Node{ 
    char* key; 
    void* value; 
    struct Node* next; 
}; 

struct symbolTable{ 
    struct Node* head; 
    int length; 
}; 

SymTable_T SymTable_new(void){ 

/* code */ 

} 

И main.c:

#include "symtable.h" 

int main(int argc, const char * argv[]) { 
    // insert code here... 
    SymTable_T emptyTable = SymTable_new(); 

    emptyTable->length = 3; <------- ERROR 

    return 0; 
} 

I'm getting error: Incomplete definition of type "struct symbolTable"

Может кто-нибудь, пожалуйста, дайте мне подсказку?

Причина, по которой я объявляю свою структуру в исходном файле, заключается в том, что у меня будет другая реализация для файла заголовка. так есть ли другой способ исправить мою ошибку при перемещении моей объявления структуры?

+0

Предлагаем разместить определения структуры в файле заголовка (и исключить typedef структуры), а затем включить этот заголовочный файл, если вы хотите объявить экземпляр структуры. – user3629249

ответ

4

Вы не можете получить доступ к элементам напрямую с помощью непрозрачного указателя - если вы сохраните реализацию в отдельном исходном файле, вам придется получить доступ ко всем членам через ваш интерфейс, а не напрямую связываться со структурой.

Например, добавьте в symtable.h:

void SymTable_set_length(SymTable_T table, int len); 

это symtablelist.c:

void SymTable_set_length(SymTable_T table, int len) 
{ 
    table->length = len; 
} 

и main.c изменить это:

emptyTable->length = 3; 

к этому:

SymTable_set_length(emptyTable, 3); 

, хотя в данном конкретном случае передача длины в качестве аргумента SymTable_new() является, безусловно, превосходным решением. Еще большее преимущество не позволяет пользователю установить длину структуры данных связанного списка вообще - длина - это количество элементов в нем, и это то, что есть. Не имеет смысла, например, добавить в список три элемента, а затем разрешить main.c установить длину до 2. symtablelist.c может рассчитать и сохранить длину в частном порядке, а main.c может узнать, какова длина, но не имеет смысла для main.c, чтобы иметь возможность задавать длину напрямую. В самом деле, весь смысл скрывать элементы структуры за непрозрачным указателем, подобным этому, заключается в том, чтобы не допустить, чтобы клиентский код мог взаимодействовать с подобными данными и нарушать инварианты структуры данных таким образом.

Если вы хотите получить доступ к элементам напрямую в main.c, тогда вам нужно, чтобы определение структуры было видимым, альтернативы нет. Это будет означать либо поместить определение структуры в файл заголовка (рекомендуется), либо дублировать его в main.c (крайне не рекомендуется).

3

В typedef symbolTable *SymTable_T; вы ссылаетесь на несуществующий тип symbolTable. В C (в отличие от C++) тип называется struct symbolTable. (Примечание: вопрос изменился, чтобы исправить это, поскольку он ответил на него.)

Вторая проблема. В main.c код должен быть способен увидеть определение struct symbolTable, для того чтобы вы могли обратиться к полям emptyTable. На данный момент определение скрыто в файле .c ... его следует перенести в заголовок.

+0

oops, извините, я поставил «struct» перед символом Table в файле заголовка. –

+0

Причина, по которой я объявляю свою структуру в исходном файле, заключается в том, что у меня будет другая реализация для файла заголовка. так есть ли другой способ исправить мою ошибку при перемещении моей объявления структуры? спасибо –

+0

Я не совсем понимаю, что вы имеете в виду. Возможно, если вы сможете сформулировать это чисто, это создаст еще один хороший вопрос, а не последует за комментариями по этому вопросу. –

Смежные вопросы