Создание собственного заголовочного файла на C

Ответы:

300

foo.h

#ifndef FOO_H_   /* Include guard */
#define FOO_H_

int foo(int x);  /* An example function declaration */

#endif // FOO_H_

foo.c

#include "foo.h"  /* Include the header (not strictly necessary here) */

int foo(int x)    /* Function definition */
{
    return x + 5;
}

main.c

#include <stdio.h>
#include "foo.h"  /* Include the header here, to obtain the function declaration */

int main(void)
{
    int y = foo(3);  /* Use the function here */
    printf("%d\n", y);
    return 0;
}

Компилировать с помощью GCC

gcc -o my_app main.c foo.c
Оливер Чарльзуорт
источник
2
@ Ану: Я не могу прочитать это в этом формате. Вы можете отредактировать свой оригинальный вопрос, чтобы включить этот код.
Оливер Чарльзуорт
3
Стоит отметить, что этот код не работает, если вы пытаетесь просто собрать его по кнопке (например, «построить и запустить» в Code :: Blocks). Это может показаться очевидным для вас, но для меня это первый раз, когда это произошло, и мне потребовалось довольно много времени, чтобы понять, в чем проблема.
Jeyekomon
5
@Jeyekomon: Ну, где это проблема?
Оливер Чарльзуорт
2
Никто не говорил мне, что кнопка «построить и запустить» не достаточно для всего. :-) Это было довольно неожиданно для меня (я новичок). Теперь, я думаю, мне нужно научиться использовать командную строку или make-файлы в первую очередь.
Jeyekomon
1
Мне было интересно, если бы вы могли уточнить, как скомпилировать все необходимые файлы, и не нужно ли включать foo.c в аргумент программы gcc. Как называется этот метод или какая программа может выполнить это вне среды IDE - мне приходит в голову
Make
26
#ifndef MY_HEADER_H
# define MY_HEADER_H

//put your function headers here

#endif

MY_HEADER_H служит в качестве охранника двойного включения.

Для объявления функции вам нужно только определить сигнатуру, то есть без имен параметров, например:

int foo(char*);

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

Это объявляет функцию, fooкоторая принимает char*и возвращает int.

В вашем исходном файле вы должны иметь:

#include "my_header.h"

int foo(char* name) {
   //do stuff
   return 0;
}
Флавий
источник
Они известны как объявления функций или прототипы функций , а не как «заголовки функций». Заголовки - это файлы, которые вы включаете, а не объявления внутри них.
Джонатан
@JonathanWakely Это заголовочные файлы. Название говорит само за себя: заголовочные файлы содержат заголовки. Но спасибо за отзыв, это заставило меня задуматься на секунду.
Флавиус
Нет, заголовки - это сами файлы, а не объявления, которые они содержат. Можете ли вы найти единственную уважаемую ссылку для резервного копирования вашего использования "заголовка"? Это противоречит, например, K & R, стандарту C, среде программирования UNIX и Wikipedia .
Джонатан
@JonathanWakely вы действительно читали K & R? В оглавлении есть раздел «4.5 Заголовочные файлы», а «Заголовочные файлы» выделены курсивом с указанием терминологии. В остальной части книги авторы для краткости пишут иногда просто «заголовок», но с помощью форматирования и оглавления ясно, какова правильная терминология. Поэтому, пожалуйста, будьте профессионалом и узнайте, когда вы ошибаетесь.
Флавий
Да, и «заголовок» относится к файлам , а не к объявлениям в них. Во 2-м издании см. Стр. 241 для обсуждения стандартных заголовков и стр. 33, где говорится об определениях и объявлениях (которые вы ошибочно называете «заголовками функций») и четко определяется заголовок : «Обычная практика - собирать externобъявления переменных и функции в отдельном файле, исторически называемом заголовком , который включается #includeв начало каждого исходного файла. Функции стандартной библиотеки, например, объявляются в заголовках как <stdio.h>. "
Джонатан
8

myfile.h

#ifndef _myfile_h
#define _myfile_h

void function();

#endif

myfile.c

#include "myfile.h"

void function() {

}
TommyGunn32
источник
void function();так как декларация не мешает звонкам вроде function(42);. Используйте voidв объявлении какvoid function(void);
chux - Восстановить Монику
5

Заголовочные файлы содержат прототипы для функций, которые вы определяете в файле .c или .cpp / .cxx (в зависимости от того, используете ли вы c или c ++). Вы хотите поместить # ifndef / # define вокруг вашего .h кода, чтобы, если вы включаете один и тот же .h дважды в разные части ваших программ, прототипы включаются только один раз.

client.h

#ifndef CLIENT_H
#define CLIENT_H

short socketConnect(char *host,unsigned short port,char *sendbuf,char *recievebuf, long rbufsize);


#endif /** CLIENT_H */

Затем вы реализуете .h в файле .c следующим образом:

client.c

#include "client.h"

short socketConnect(char *host,unsigned short port,char *sendbuf,char *recievebuf, long rbufsize) {
 short ret = -1;
 //some implementation here
 return ret;
}
djsumdog
источник
«так что если вы включаете один и тот же .h дважды в разные части ваших программ, прототипы включаются только один раз». Это вводит в заблуждение. Они защищают от включения одного и того же заголовочного файла дважды из одного и того же исходного файла (включая заголовок дважды в двух разных исходных файлах, это нормально и обычно требуется!), И повторное объявление прототипов функций не является проблемой, переопределение типов и глобальных переменных это то, что должно быть защищено от.
Джонатан