Linguagem C: Modularização

De Aulas

Links relacionados: Programação em C

Modularização

Quando o código é pequeno, basta colocarmos nosso algoritmo bem organizado em um arquivo. Contudo, quanto maior a quantidade de linhas de código, mais complexo pode ficar para que possamos entender nosso programa. Uma forma de modularizar é separar em funções, como já vimos nas aulas anteriores. Mesmo assim, depois de algumas boas linhas de código, navegar no arquivo cheio de códigos, começa a ficar um pouco complicado.

Para isso, podemos separar nosso código em outros arquivos, criando nosso próprio conjunto de bibliotecas. Em geral, separamos nossas bibliotecas tendo cada arquivo as funções que possuem funções correlacionadas, como biblioteca matemática, biblioteca de gerenciamento de um arquivo, biblioteca para manipulação de informações de entrada de determinado sensor, etc..

No C, para cada arquivo de biblioteca "arquivo.c", devemos ter um arquivo de cabeçalho (ou header) com o mesmo nome, mas com extensão .h: "arquivo.h". No arquivo H colocamos os protótipos das funções que iremos precisar, e no arquivo C a gente implementa essas funções.

Porque separar os arquivos em .H e .C? Bem existem vários motivos, mas de forma simples, muitas vezes queremos poder distribuir bibliotecas que implementamos sem fornecer os códigos fontes das mesmas. Então distribuímos as bibliotecas em arquivos compilados, e os arquivos .H são a forma como o programa que implementamos vão ver as funções que estão nas bibliotecas compiladas, ou seja, é a assinatura das mesmas e possui a interface para acessar aquelas funções.

A seguir temos um exemplo de criação de um arquivo de biblioteca.

bib.h

Arquivo cabeçalho com os protótipos das funções que queremos implementar.

 1#ifndef BIB_H
 2#define BIB_H
 3
 4// Verificar se numero par
 5int isEven(int num);
 6
 7// Transforma um número float em string
 8char* floatToString(float value);
 9
10#endif // BIB_H

a estrutura #ifndef-#define-#endif é importante para não deixar o compilador incluir mais de uma vez a mesma biblioteca, senão dará erro de compilação. Assim, da primeira vez que o compilador tenta incluir esse cabeçalho, ele cria uma constante, nesse caso foi criada a constante BIB. Se ele tentar fazer isso uma segunda vez, verificará que já existe a constante BIB, e não inclui novamente este cabeçalho.

bib.c

Arquivo com as funções implementadas.

 1#include <string.h>
 2#include <stdio.h>
 3#include <stdlib.h>
 4
 5int isEven(int num) {
 6    if (num % 2 > 0) {
 7        return 0;
 8    }
 9    return 1;
10}
11
12char* floatToString(float value) {
13    char* out = malloc(10 * sizeof(char));
14    sprintf(out, "%.2f", value);
15    return out;
16}

main.c

Arquivo do programa, que utiliza as funções implementadas nas bibliotecas.

 1#include <stdio.h>
 2#include <stdlib.h>
 3#include "bib.h"
 4
 5int main() {
 6    int n = 4;
 7    float f = 3.141614;
 8    char *s = floatToString(f);
 9    printf("Numero %d eh par? %d\n", n, isEven(n));
10    printf("Isso é uma string: %s.\n", s);
11    free(s);
12}

Compilar

Para compilar, basta entrar na pasta e compilar os arquivos com o comando:

gcc *.c -o nome_executavel