Оператор #include "file2.c"
эффективно включает содержимое file2.c
в file1.c
. Затем file1.c
компилируется так, как если бы оно содержало:
int function2()
{
return 2018;
}
Эти строки определяют function2
; они сообщают компилятору: «Вот function2
, создайте для него код». Поскольку эти строки фактически появляются в file1.c
и file2.c
, ваша программа имеет две копии function2
.
Вместо этого вы должны создать file2.h
, который содержит:
int function2();
Эта строка сообщает компилятору: «Существует функция с именем function2
, но ее определение где-то еще».
Затем в file1.c
используйте #include "file2.h"
вместо #include "file2.c"
. Это сообщит компилятору во время компиляции file1.c
, что ему нужно знать, чтобы скомпилировать вызов function2
. Компилятор будет иметь объявление , в котором он нуждается, но у него не будет определения , которое не нужно в file1.c
.
Также в file2.c
вставить #include "file2.h"
. Тогда file2.c
будет содержать как объявление function2
(из file2.h
), так и определение function2
(из фактических строк в file2.c
). Цель этого состоит в том, чтобы компилятор мог видеть и объявление, и определение во время компиляции file2.c
, поэтому он может предупредить вас, если есть опечатка, которая делает их несовместимыми.
Кроме того, в C вы должны использовать int function2(void)
вместо int function2()
. По историческим причинам последний оставляет параметры неуказанными. Использование (void)
сообщает компилятору об отсутствии параметров.