Вы написали функции, которые работают. Генератор rand и алгоритм bubble_sort надежны. Теперь вам нужно использовать их в других местах. Копирование и вставка кода — это беспорядок. Это создает ошибки. Это превращает поддержку в кошмар.

Решение — библиотека утилит.

В C библиотека — это не магический ящик. Это два конкретных файла, работающих вместе: заголовочный файл (.h ) и исходный файл (.c ). Заголовочный файл сообщает компилятору, что доступно. Исходный файл содержит саму логику.

Вот как структурировать базовую библиотеку на C, чтобы поддерживать чистоту и модульность вашего кода.

Определение интерфейса

Каждая публичная функция должна иметь объявление. Оно находится в заголовочном файле.

Создайте файл с именем util.h.

Эти строки являются прототипами функций. Ключевое слово extern важно. Оно сообщает компилятору: «Эта функция существует, но я пока не знаю, где именно. Я найду её позже на этапе линковки».

Если вы используете очень старый компилятор C, возможно, вам придется удалить имена параметров из bubble_sort. Современные стандарты предпочитают полные прототипы, но устаревший код часто их убирает.

Реализация логики

Теперь о самой сложной части. Создайте util.c.

Обратите внимание на подключение. Вы используете кавычки ("util.h" ), а не угловые скобки ( ). Угловые скобки зарезервированы для системных библиотек, находящихся в стандартных директориях. Кавычки говорят компилятору искать файл в текущей директории.

Здесь есть тонкая функция безопасности. Переменная rand_seed определена в файле .c, но не в файле .h. Это сокрытие информации.

Программы, включающие util.h, знают о rand(). Они не знают о rand_seed. Они не могут случайно изменить seed (начальное значение). Если вы хотите обеспечить это строго, вы можете добавить ключевое слово static перед int rand_seed. Это сделает переменную видимой только внутри этого единственного файла.

Использование библиотеки

Ваша основная программа не нуждается в реализации. Ей нужен только интерфейс.

Создайте main.c.

Преимущество очевидно. Основная логика становится короче. Вы не загромождаете основной код алгоритмами сортировки или генераторами случайных чисел. Вы просто вызываете их.

Компиляция и линковка

Здесь большинство новичков спотыкаются. Вы не можете компилировать всё сразу, если хотите получить отдельные объектные файлы. Вам нужно компилировать их по отдельности, а затем линковать.

Предполагая, что вы работаете в системе, похожей на UNIX, вот рабочий процесс.

Сначала скомпилируйте исходный код библиотеки в объектный файл.

Флаг -c говорит GCC компилировать, но не линковать. Он останавливается после создания машинного кода. Флаг -g добавляет отладочные символы, что полезно, если что-то пойдет не так. Результатом станет файл util.o. Этот файл содержит скомпилированный машинный код для rand и bubble_sort. Он не может выполняться самостоятельно, так как в нем отсутствует функция main.

Затем скомпилируйте вашу основную программу.

Это создает файл main.o. Опять же, это просто машинный код. Это еще не исполняемый файл.

Наконец, свяжите их вместе.

Эта команда берет main.o и util.o и объединяет их в один исполняемый файл с именем main.

Запустите его с помощью:

Вы увидите список из десяти случайных чисел, за которым следует разделитель в виде тире, а затем отсортированный список.

Почему это важно

Вы можете спросить: зачем заморачиваться с этим дополнительным шагом? Почему бы просто не вставить функции в main.c?

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