Вам не хватает файла заголовка.
C компилирует каждый исходный файл в объектные файлы отдельно.Тогда это связывает их вместе.Каждый файл .c должен знать сигнатуру всех типов и функций, которые он использует.Это означает, что test_list.c
должен знать сигнатуры структур и функций в list.c
.В настоящее время это не так.
Вы можете напрямую включить list.c
в test_list.c
с #include list.c
, который в основном вставляет list.c
в test_list.c
.Это будет работать, но тогда list.c
не может использоваться никаким другим файлом, не вызывая всевозможных проблем.
Лучше создать файл заголовка , который объявляет все ваши типы и forward объявляет все ваши функции.Предварительная декларация позволяет компилятору узнать, какие функции доступны и какова их подпись, с обещанием, что функция будет определена позже чем-то другим.
// list.h
struct nodeStruct {
int item;
struct nodeStruct *next;
};
struct nodeStruct* List_createNode(int);
void List_insertHead (struct nodeStruct **, struct nodeStruct *);
Теперь и test_list.c
, и list.c
могут #include "list.h"
предоставить компилятору достаточно информации для компиляции каждого исходного файла в объектный файл.Затем объекты будут связаны между собой и сообщат test_list.o, где найти функции в list.o.
# Compile list.c into list.o using the declarations in list.h
cc -c -g -w -std=c99 -Wall -Werror list.c
# Compile test_list.c into test_list.o using the declarations in list.h
cc -c -g -w -std=c99 -Wall -Werror test_list.c
# Link both object files into an executable so test_list.o can
# use the functions compiled into list.o
cc -o test_list list.o test_list.o