Você escreveu funções que funcionam. O gerador rand e o algoritmo bubble_sort são sólidos. Agora você precisa deles em outro lugar. O código de copiar e colar é confuso. Isso cria bugs. Isso torna a manutenção um pesadelo.

A solução é uma biblioteca utilitária.

Em C, uma biblioteca não é uma caixa mágica. São dois arquivos específicos trabalhando juntos: um cabeçalho (.h ) e uma fonte (.c ). O cabeçalho informa ao compilador o que está disponível. O arquivo de origem contém a lógica real.

Veja como você estrutura uma biblioteca C básica para manter seu código limpo e modular.

Definindo a interface

Toda função pública precisa de uma declaração. Isso fica no arquivo de cabeçalho.

Crie um arquivo chamado util.h.

Essas linhas são protótipos de funções. A palavra-chave extern é importante. Diz ao compilador: “Esta função existe, mas ainda não sei onde. Vou encontrá-la mais tarde, durante a vinculação.”

Se você estiver usando um compilador C de estilo muito antigo, pode ser necessário remover os nomes dos parâmetros de bubble_sort. Os padrões modernos preferem protótipos completos, mas o código legado geralmente os elimina.

Implementando a Lógica

Agora, para o trabalho pesado. Crie util.c.

Observe a inclusão. Você usa aspas ("util.h" ) em vez de colchetes angulares ( ). Os colchetes angulares são reservados para bibliotecas do sistema encontradas em diretórios padrão. As aspas dizem ao compilador para procurar no diretório atual.

Há um recurso de segurança sutil aqui. A variável rand_seed é definida no arquivo .c, mas não no arquivo .h. Isso é ocultação de informações.

Programas que incluem util.h conhecem rand(). Eles não sabem sobre rand_seed. Eles não podem modificar acidentalmente a semente. Se você quiser impor isso estritamente, você pode adicionar a palavra-chave static antes de int rand_seed. Isso torna a variável visível apenas neste único arquivo.

Usando a biblioteca

Seu programa principal não precisa de implementação. Ele só precisa da interface.

Crie main.c.

O benefício é imediato. A lógica principal é mais curta. Você não sobrecarrega seu código primário com algoritmos de classificação ou geradores de números aleatórios. Você acabou de ligar para eles.

Compilando e vinculando

É aqui que a maioria dos iniciantes tropeça. Você não pode compilar tudo de uma vez se quiser arquivos de objetos separados. Você tem que compilar separadamente e depois vincular.

Supondo que você esteja em um sistema semelhante ao UNIX, aqui está o fluxo de trabalho.

Primeiro, compile o código-fonte da biblioteca em um arquivo objeto.

O sinalizador -c diz ao GCC para compilar, mas não vincular. Ele para após a criação do código de máquina. O sinalizador -g adiciona símbolos de depuração, o que é útil se algo der errado. O resultado é util.o. Este arquivo contém o código de máquina compilado para rand e bubble_sort. Ele não pode funcionar sozinho porque não possui uma função principal.

A seguir, compile seu programa principal.

Isso produz main.o. Novamente, isso é apenas código de máquina. Ainda não é um executável.

Finalmente, vincule-os.

Este comando pega main.o e util.o e os une em um único executável chamado main.

Execute-o com:

Você verá uma lista de dez números aleatórios, seguidos por um traço separador, seguido pela lista ordenada.

Por que isso é importante

Você pode perguntar: por que se preocupar com essa etapa extra? Por que não colar as funções em main.c?

Porque as bibliotecas são escalonáveis. À medida que seus projetos crescem, você terá dezenas de funções utilitárias. Mantê-los em arquivos separados permite reutilizá-los em diferentes projetos