C/C++

Модули. Коммуникация между двумя .c файлами.(Си)

Коммуникация между main.c и header.h мне совершенно понятна. Но так же и непонятна коммуникация между двумя .c файлами.
Здесь описан пример: https://server.179.ru/tasks/cpp/total/103.html

//#include "hello.h"
#ifndef HELLO_H
void hello_world();
#endif //HELLO_H

int main()
{
hello_world();
return EXIT_SUCCESS;
}

Как файл main.c получает данные с файла hello.c?
В файле hello.h ссылок на файл hello.с нет.
Игорь _
Игорь _
288
А чем вообще .h от .c отличаются, не думал?
В файле .h функция объявлена, но не реализована (нет ее кода), это значит, что нужно поискать во всех .c
Грубо говоря, так.
КС
Киселев Сергей
92 464
Лучший ответ
Игорь _ Грубо говоря ничего непонятно.
Любой хеадер файл проекта связан с любым .с файлом проекта?
Игорь _ Так можно это представить? :
Когда я подключаю хеадер файл, то я подключаю все .с файлы проекта вместе с этим хеадер файлом.
Игорь _ И вообще тогда зачем посредник нужен в качестве хеадер файла? Может .с файлы проекта и так связаны между собой?
Есть понятие проекта, то бишь все файлы которые будут компилировать, а потом соберутся в 1 объектный файл. Там большая таблица всех глобальных переменных, да всех функций. Вот h и говорить должно, что за файл, класс - короче, как бы что за тип, каков размер, что принимает, что отдает. А реализация этой функции по сути место куда надо обратиться с такими-то параметрами и что мы получим.
Гарик Гарик
Гарик Гарик
80 606
Игорь _ Грубо говоря ничего непонятно.
Любой хеадер файл проекта связан с любым .с файлом проекта?
Игорь _ Так можно это представить? :
Когда я подключаю хеадер файл, то я подключаю все .с файлы проекта вместе с этим хеадер файлом.
Игорь _ И вообще тогда зачем посредник нужен в качестве хеадер файла? Может .с файлы проекта и так связаны между собой?
Игорь _ Кароче в заголовочных файлах находятся заголовки. Когда main.c находит этот заголовок (например функции), то даёт команду искать продолжение этого кода во всех .с файлах?
Хммм, я понял потому что я сообразительный)), но мне кажется хромает ваше объяснение))
Игорь _ Я вообще не понимаю зачем писать #ifndef
Это от защиты что может в одном модуле программист сделал уже работу за другого программиста и объявил функцию о названии которой ничего не знает?)
Компилятору непосредственно передаются только .c-файлы. Когда компилятор видит директиву
#include "hello.h"
он тупо подставляет содержимое файла hello.h вместо строки #include.
Смысл в том, чтоб вставить один фрагмент текста (файл hello.h) в несколько файлов .c
По-хорошему в файле hello.c должны быть реализованы функции, объявленные в файле hello.h. То же самое с глобальными переменными. Но это не обязательно так. Например, если файл hello.c получается очень большим, можно разделить его на несколько файлов. Чтоб всех запутать, файл hello.c можно обозвать как-то по-другому. Для компилятора это не имеет значения.
Заголовочные файлы тоже могут подключать друг друга. Важно только, чтоб не было циклов: если файл А подключает файл Б, то файл Б не может подключать файл А.
Каждый .c-компилируется в отдельный объектный файл (с расширением obj или o). Потом линковщик (компоновщик) собирает объектные файлы в исполняемый файл. При этом используются ещё объектные и lib-файлы библиотек.
Олег Еремкин
Олег Еремкин
58 065
Игорь _ >> Важно только, чтоб не было циклов: если файл А подключает файл Б, то файл Б не может подключать файл А.
Если применить #ifndef, то может и можно делать циклы.
Файлы заголовка (.h) - это просто текстовые файлы, содержимое которых вставляется в .c файл в месте, где объявляется директива #include. Больше никакого сакрального значения они не имеют.

Компилятор берет .c файл, и сначала запускает для него программу, которая называется препроцессор. Эта программа и заменяет все #include "... h" на содержимое соответствующих файлов заголовка. Препроцессор также ответственен за обработку других директив типа #define и пр. После того, как препроцессор отработал, он отдает обработанный .c файл непосредственно на компиляцию, которая, в свою очередь, для каждого такого .c файла генерит объектный файл .obj. Потом за работу берется линкер, который "сшивает" все объектные файлы в один исполняемый файл.
Игорь _ Вопрос был в друго. Но я уже разобрался.