в последнее время мне пришлось изучать C lang, когда я добрался до раздела файла заголовка, я заметил, что мне нужно включить файл заголовка, содержащий прототипы, в исходный код вызова, а также в исходный файл, где я определил эти функции в первую очередь.
скажем, в файле file.c я хочу назвать прототипы заголовков myheader.h . Затем я должен включить заголовок #include "myheader.h" в file.c, что понятно.
но почему я не могу понять, так это то, что я должен включить его и в файл определения прототипа proto_source.c:
/**
* THE PROTYPES DEFINITION SOURCE proto_source.c
*/
#include "myheader.h" //what this include is doing here?
void foo(void)
{
....
}
Какая логика стоит за этим?
@ Fe2O3 Fe2O3, это было проницательно, но не могли бы вы объяснить подробнее или отослать меня к более подробному источнику по этому вопросу?
Вы проверяли, что происходит, когда вы оставляете его выключенным?
Также нередко функции в исходном файле вызывают другие (нестатические) функции в том же исходном файле. Вместо того, чтобы добавлять прототипы в исходный файл, просто #include свой собственный заголовок.
Обратите внимание, что вам не нужно включать заголовок в соответствующий исходный файл. Это хорошая практика, но не всегда необходимая.
Учитывая вашу настройку, он строится. И foo вызывается из file.c с foo(). Теперь вы редактируете proto_source.c и меняете на void foo(struct baz *ptr) { ptr->val = 5; }. Но вы не меняете .h. Теперь вызов foo неверен, и foo будет segfault во время выполнения. Однако без «оскорбления» #include (в proto_source.c) он будет строиться чисто. При включении несоответствие прототипа будет обнаружено во время компиляции.
Связанный: stackoverflow.com/a/56961715/6699433
Заголовки — это связующее звено, скрепляющее программу на C. Заголовки позволяют потребителям набора библиотечных функций узнать, что такое интерфейсы. Включение заголовков в реализацию обычно необходимо (например, если есть типы структур или перечисления и т. д.) и перекрестная проверка того, соответствует ли реализация обещанным заголовкам. В C99 или более поздних версиях у вас должно быть объявление каждой функции, доступное перед ее вызовом, а объявление ее в заголовке избавляет вас от многократного написания объявления, обеспечивает согласованность и позволяет избежать проблем с множественным обслуживанием.





Выполнение этого в C считается полезным, поскольку опытный компилятор укажет на несоответствия между прототипом функции и ее реализацией. Кроме того, в сложных сценариях вам может потребоваться объявить структуру или что-то подобное в заголовочном файле, на который опирается ваша функция. Во избежание дублирования предпочтительным подходом является включение файла заголовка.
Просто компилятор также проверяет соответствие определения функции прототипу, который находится в заголовочном файле, и сообщает о несоответствиях. Все должны согласиться с типом и количеством параметров и возвращаемым значением.