Во-первых, вы немного озадачены тем, что происходит с #include. Вы никогда не «компилируете» стандартную библиотеку. Стандартная библиотека уже скомпилирована и находится в файлах библиотеки (файлы .dll и .lib в Windows, .a и .so в Linux). Что делает #include, так это дает вам объявлений , необходимых для ссылки на стандартную библиотеку.
Первое, что нужно понять о директивах #include, это то, что они очень низкого уровня. Если вы программировали на Java или Python, #include сильно отличается от импорта. Импорт сообщает компилятору на высоком уровне «этот исходный файл требует использования этого пакета», и компилятор выясняет, как разрешить эту зависимость. Директива #include in C гласит: «возьмите все содержимое этого файла и буквально вставьте его прямо здесь при компиляции». В частности, #include <stdio.h>
вводит файл, который имеет предварительные объявления для всех функций ввода / вывода в стандартной библиотеке. Затем, когда вы компилируете свой код, компилятор знает, как выполнять вызовы этих функций и проверять их на корректность типов.
Как только ваша программа скомпилирована, она связывается со стандартной библиотекой. Это означает, что ваш компоновщик (который автоматически вызывается вашим компилятором) либо заставит ваш исполняемый файл использовать общую стандартную библиотеку (.dll или .so), либо скопирует необходимые части статической стандартной библиотеки (.lib или .a) в ваш исполняемый файл. Ни в том, ни в другом случае ваш исполняемый файл не "содержит" какую-либо часть стандартной библиотеки, которую вы не используете.
Что касается создания библиотеки, то это немного сложная тема, и я оставлю это другим, тем более, что я не думаю, что это то, что вы действительно хотите сделать, основываясь на следующей части вашего вопроса.
Заголовочный файл не всегда является частью библиотеки. Кажется, что у вас есть несколько исходных файлов, и вы хотите иметь возможность использовать функции из одного исходного файла в другом исходном файле. Вы можете сделать это без создания библиотеки. Все, что вам нужно сделать, это поместить объявлений для файлов foo.c, к которым вы хотите получить доступ из других мест, в foo.h. Объявления - это такие вещи, как прототипы функций и объявления переменных "extern". Например, если foo.c содержит
int some_global;
void some_function(int a, char b)
{
/* Do some computation */
}
Затем, чтобы сделать их доступными из других исходных файлов, foo.h должен содержать
extern int some_global;
void some_function(int, char);
Затем вы #include "foo.h"
везде, где вы хотите использовать some_global или some_function. Поскольку заголовки могут включать в себя другие заголовки, обычно заголовки заключаются в «включить охранники», чтобы объявления не дублировались. Например, foo.h должен действительно читать:
#ifndef FOO_H
#define FOO_H
extern int some_global;
void some_function(int, char);
#endif
Это означает, что заголовок будет обрабатываться только один раз на единицу компиляции (исходный файл).
Что касается того, как их компилировать, никогда не помещайте файлы .h в командную строку компилятора, поскольку они не должны содержать какой-либо компилируемый код (только объявления). В большинстве случаев это прекрасно для компиляции как
cc main.c 1.c 2.c 3.c ... [etc]
Однако, если у вас 50 исходных файлов, возможно, будет гораздо удобнее, если вы используете систему сборки. В Linux это Makefile. От окон зависит, какую среду разработки вы используете. Вы можете зайти в Google или задать еще один вопрос, как только укажете платформу (так как этот вопрос уже достаточно широк).
Одним из преимуществ системы сборки является то, что они компилируют каждый исходный файл независимо, а затем связывают их все вместе, так что, когда вы изменяете только один исходный файл, необходимо перекомпилировать только этот файл (и программу перекомпилировано) вместо того, чтобы перекомпилировать все, включая то, что не изменилось. Это делает большую разницу во времени, когда ваша программа становится большой.