Сообщение компилятора довольно ясно.Тип является неполным, что в основном означает, что компилятор знает только, что существует структура с именем Graph, но он не знает, как он выглядит.Следствием этого является то, что вы не можете получить доступ к полям.
Итак, сначала вы должны ответить на этот вопрос.Хотите ли вы, чтобы программист, использующий библиотеку, имел доступ к полям Graph?Если нет, поместите определение в файл .c.Если да, поместите определение в файл .h.
Еще одна вещь, которую следует учитывать, - typedef struct Graph * Graph
.Вы скрываете очень много информации при определении типа структуры, и то же самое относится и к типу определения указателя.Теперь вы делаете оба.Мое личное мнение таково, что вам действительно следует избегать этого, если только ответ на поставленный выше вопрос не является «нет».
Я предлагаю, если вы хотите, чтобы пользователь библиотеки имел доступ к полямstruct Graph, полностью удалите typedef.Если вы хотите скрыть это от пользователя, используйте функции доступа к коду, например:
// cities.h
int getNodeCount(Graph g);
// cities.c
int getNodeCount(struct Graph * g) {
return g->nodeCount;
}
И используйте это так:
Graph g;
int nodeCount = getNodeCount(g);
Обратите внимание, что я НЕиспользуйте typedef в определении функции.Только в его прототипе.