Ваша первая проблема, как указано в моем комментарии, заключается в том, что вы включили исходный файл. Вы включаете только заголовки, так что есть прототипы и код компилируется, но вы не включаете другие файлы кода - они компилируются отдельно. Это не разрушает единственное преимущество, которое имеет отдельная компиляция: более быстрая перекомпиляция, поскольку между каждой компиляцией изменяется только несколько исходных файлов, и неизмененные файлы не нужно снова компилировать, поскольку файлы .obj все еще там.
Исправляя это, ваша проблема должна исчезнуть. Но не навсегда, только пока проект остается таким маленьким, и вы ничего не включаете несколько раз. Каждый заголовочный файл (ну, каждый файл, который вы включили - но это только заголовки) должен иметь «include guard», который предотвращает многократное включение файла (помните, #include "file"
означает только «вставить содержимое file
здесь»). перед компиляцией ") - main.c
включает definitions.h
и functions.c
, но functions.c
также включает definitions.h
, поэтому содержимое definitions.h
включается дважды, следовательно, все типы и прототипы функций фактически определяются дважды - что незаконно. В самом начале каждого заголовочного файла поместите что-то вроде этого:
#ifndef UNIQUE_HEADER_NAME_H
#define UNIQUE_HEADER_NAME_H
И в самом конце поставить #endif
(некоторые предпочитают #endif //UNIQUE_HEADER_NAME_H
после endif, для пояснения). Поэтому при первом включении файла UNIQUE_HEADER_NAME_H
не определяется, поэтому файл включается как обычно , а UNIQUE_HEADER_NAME_H
определяется. И в следующий раз, когда он будет включен, UNIQUE_HEADER_NAME_H
уже определен, таким образом, препроцессор переходит к соответствующему endif (тому, который находится в конце, если вы не пропустили его в фактическом заголовке), и ничего не включается дважды.