Вот (первая) ошибка, которую я получаю, когда пытаюсь скомпилировать этот набор файлов:
$ cc main.c
In file included from main.c:4:
In file included from ./ListHeadTail.h:4:
In file included from ./Student.h:6:
./Friend.h:11:19: error: unknown type name 'List'
void printFriends(List *l);
Посмотрите на имена файлов и номера строк. Обратите внимание, что в строке 4 ListHeadTail.h вы уже определили LISTHEADTAIL_H
, но еще не достигли фактического объявления List
. Затем вы идете в Student.h, а оттуда в Friend.h. Это снова включает ListHeadTail.h - но поскольку LISTHEADTAIL_H
уже определено, это включение ничего не делает. Таким образом, вы продолжаете через Friend.h без объявления List
, и, следовательно, получаете ошибку в объявлениях, которые ссылаются на него.
Как отметил @lurker в своем комментарии, основной проблемой здесь является циклическая зависимость, а простым исправлением является предварительное объявление. В этом случае вы можете просто изменить Friend.H, заменив #include "ListHeadTail.h"
на typedef struct list List;
.
Но для меня это немного глупо. Если вы где-то измените порядок включений, сборка может снова прерваться.
Я думаю, что реальная проблема заключается в том, что объявления функций (printFriends
и т. Д.) Не принадлежат Friend.h; они принадлежат в ListHeadTail.h. Функции не имеют ничего общего с типом Friend
. Конечно, у них есть «Друг» в их именах, но единственный тип, на который ссылаются в объявлениях, это List
. Таким образом, они принадлежат ListHeadTail.h. То же самое касается функции changeData
в Student.h.
В объектно-ориентированном дизайне (скажем, в Java) все эти функции, вероятно, будут методами класса List и будут объявлены в исходном файле этого класса.