Вы написали код. Он работает. Но теперь вы хотите использовать генератор rand() или процедуру bubble_sort в совершенно другом проекте. Копирование и вставка — это лень. Это также хрупкий подход. Когда вы обновляете одну версию, вам приходится искать каждую копию кода.
Профессиональное решение? Создайте библиотеку.
В экосистеме C библиотека — это не магический черный ящик. Это всего лишь два файла, выполняющие разные роли. Вам нужен заголовочный файл (.h ) и исходный файл (.c ). Заголовочный файл сообщает остальному миру, какие функции существуют. Исходный файл выполняет реальную работу.
Создание интерфейса: util.h
Заголовочный файл действует как контракт. Он не содержит логики. Он содержит обещания. Константы, типы и прототипы функций.
Создайте файл с именем util.h.
Ключевые слова extern выполняют тяжелую работу. Они говорят компилятору: «Не ищи реализацию здесь. Я найду её позже во время линковки». Если вы застряли на устаревшем компиляторе, предшествующем современным стандартам C, удалите параметры из bubble_sort. Старые компиляторы такие придирчивые.
Сокрытие механизмов: util.c
Теперь сам код. Сохраните это как util.c.
Обратите внимание на директиву include. Мы используем кавычки ("util.h" ), а не угловые скобки ( ). Разница имеет значение. Кавычки ищут в текущей директории. Угловые скобки ищут в системных директориях. Этот файл локальный. Он принадлежит здесь.
Вот тонкий момент: rand_seed. Он находится в util.c. Его нет в util.h. Это сокрытие информации в действии. Код, использующий эту библиотеку, может вызывать rand(), но не может напрямую обращаться к seed (зерну). Состояние инкапсулировано. Для строгого контроля вы можете добавить ключевое слово static перед определением переменной. Это надежно блокирует доступ. Никакого внешнего доступа. Точка.
Использование библиотеки: main.c
Теперь напишите программу, которая её использует. Сохраните это как main.c.
Короче? Да. Чище? Безусловно. Основная программа не заботится о том, как rand() генерирует числа. Она просто требует число. Это разделение и есть вся суть.
Компиляция и линковка
Как превратить эти отдельные файлы в работающий исполняемый файл? Вы следуете трехшаговому танцу.
Сначала скомпилируйте исходный код библиотеки в объектный файл. Предполагая, что вы используете UNIX-подобную систему с GCC:
Флаг -c здесь обязателен. Он говорит компилятору остановиться после создания объектного файла. Он создает util.o. Этот файл содержит машинный код, но он неполный. В нем нет функции main. Он не может работать самостоятельно. Это компонент, а не продукт.
Далее скомпилируйте вашу основную программу:
Это генерирует main.o. Опять же, просто машинный код. Все еще без логики библиотеки.
Наконец, свяжите их вместе.
Эта команда берет оба объектных файла и сшивает их в один исполняемый файл с именем main. Теперь у вас есть полная программа. Запустите её с помощью ./main (или просто main, если вы используете Windows или она добавлена в ваш PATH).
Это много шагов для двух функций. Но представьте, если бы вы делали это для проекта с пятьюдесятью файлами. Вы компилируете каждый файл .c один раз. Вы связываете их вместе. Изменили функцию в библиотеке? Перекомпилируйте только этот файл. Пересвяжите. Остальное остается нетронутым.
Makefiles автоматизируют этот

























