Подтвердить что ты не робот

Любое фундаментальное различие между исходными и заголовочными файлами в C?

Я не совсем понимаю, как вещи должны быть разделены в исходных и заголовочных файлах C. Я часто вижу много проектов с двумя наборами файлов с тем же именем (без расширения, обозначающего исходные и заголовочные файлы).

До сих пор, из-за этого непонимания, когда я писал библиотеки, я вложил весь код класса и класса в один файл с нерешительностью в отношении выбора расширения файла.

Что должно быть в заголовках и что должно быть в исходных файлах? Как реализовать это разделение?

4b9b3361

Ответ 1

Нет технической разницы. Компилятор с радостью позволит вам добавить файл .c или скомпилировать файл .h, если хотите.

Существует, однако, огромное культурное различие:

  • Объявления (прототипы) входят в файлы .h. Файл .h является интерфейсом к тому, что реализовано в соответствующем файле .c.

  • Определения входят в файлы .c. Они реализуют интерфейс, указанный в файле .h.

Разница в том, что файл .h может (и обычно будет) #include d на несколько единиц компиляции (.c files). Если вы определите функцию в файле .h, она окажется в нескольких файлах .o, и компоновщик будет жаловаться на многократно определенный символ. Вот почему определения не должны входить в файлы .h. (Исключением являются встроенные функции.)

Если функция определена в файле .c и вы хотите использовать ее из других файлов .c, объявление этой функции должно быть доступно в каждом из этих других файлов .c. Вот почему вы помещаете объявление в .h и #include, что в каждом из них. Вы также можете повторить объявление в каждом файле .c, но это приводит к большому количеству дублирования кода и неуправляемому беспорядку.

Если функция определена в файле .c, но вы не хотите использовать ее из других файлов .c, нет необходимости объявлять ее в заголовке. Это, по сути, деталь реализации этого файла .c. В этом случае также создайте функцию static, поэтому она не конфликтует с идентично именованными функциями в других файлах.

Ответ 2

Что должно быть в заголовках и что должно быть в исходных файлах?

Обычно заголовки содержат одно или несколько из следующих элементов:

  • Объявление функции (кроме статики)
  • Объявление переменной (обычно глобальное)
  • Объявление пользовательского типа (читайте struct, union и т.д.)
  • Определение макроса

С другой стороны, исходные файлы имеют:

  • Определение функции/переменной
  • Объявление и определение статической функции (вы не хотите раскрывать их своим клиентам)
  • Переменное определение
  • Некоторые предпочитают определять встроенные функции (C99) в заголовке

Как реализовать это разделение?

Правило одного определения - ваш друг.

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

И, кстати, у C нет понятия классов.

Ответ 3

Обычно заголовочные файлы содержат декларации, исходные файлы содержат код.

Итак, если в исходном файле A.c вам нужна функция, реализованная в исходном файле B.c, вы просто включаете B.h для ее объявления.

Ответ 4

Существует незначительная принципиальная разница между .c и .h файлами (хотя некоторые компиляторы могут отказаться от компиляции файла .h). Разница более согласуется.

Обычно файл .h предоставляет API, а .c обеспечивает реализацию.

Поэтому файл .h будет содержать только вещи, необходимые для других исходных файлов, для доступа к средствам, предоставленным вашим .c файлом. Таким образом, файлы .h будут предоставлять прототипы функций глобальных функций, декларации глобальных переменных (если они действительно нужны), а также структуры и другие типы, используемые ими. (Не выставляйте структуру, если API-интерфейс требуется только указателю на структуру.)

Встроенные функции также часто включаются в файлы .h, но некоторые рекомендации по кодированию предпочитают использовать отдельное расширение (например,.inl)

Все другие реализации функций, определение и инициализация переменных и декларации локальных (статических) переменных и функций будут в файле .c.