MC102 - Lab06
Modularização em C

Organização do Código:
Os programas que vocês fizeram até agora eram compostos por um único arquivo. Uma dúvida que boa parte dos programadores iniciantes possuem é como dividir um programa em módulos. Embora não seja obrigatório particionar os programas em módulos, recomenda-se fortemente que isso seja feito, especialmente programas de um porte maior. Isso facilitará a manutenção do programa, além de minimizar a perda de tempo com compilações, já que é necessário recompilar apenas os módulos que sofreram alterações.

Todo programa em C possui pelo menos um módulo, o módulo principal, que contém a função main, podendo, eventualmente, ter módulos adicionais. Todo módulo, exceto o módulo principal, consiste de dois arquivos:

  1. Arquivo com extensão .C contendo a implementação do módulo;
  2. Arquivo de cabeçalho do módulo com extensão .H (header file).
    O módulo principal não possui cabeçalho.

Basicamente módulos apresentam conjuntos de funções agrupadas de acordo com algum critério semântico. Os detalhes de implementação dessas funções devem ficar no arquivo .C do módulo, e tudo o que for importante para o usuário conseguir utilizar o módulo, (interface do módulo) deve ficar no arquivo .H. Compõem esses cabeçalhos as declarações de constantes, tipos, variáveis e protótipos de funções.

O protótipo de uma função:
Em C, para que se possa usar uma variável, constante ou função, a mesma deve ter sido previamente declarada. No caso de uma função, essa "declaração" pode ser feita de duas formas:

  1. Através da implementação da função, que é a declaração completa da mesma (o que foi visto nos exemplos de aula apresentados até agora).
  2. Através do protótipo da mesma. O protótipo de uma função declara a mesma sendo que a sua implementação correspondente pode estar, no mesmo arquivo ou num arquivo à parte. O protótipo contém:

    Exemplos:
    int max(int a, int b);
    int soma(int a, int b);

Todo arquivo .C de módulo deve incluir (usando a diretiva #include) o seu header .H correspondente, para que o compilador possa verificar a coerência entre os protótipos das funções e as suas implementações. Devem ser incluídos também os headers de todos os módulos que lhe prestam serviços. O único módulo que não tem um header é o módulo principal, uma vez que este módulo não presta serviços a nenhum outro módulo; são os outros módulos que, diretamente ou indiretamente, lhe prestam serviços.

A diretiva #include
A diretiva #include <nome_de_arquivo> faz com que o texto contido no arquivo seja copiado (ou "incluído") num programa durante a compilação. Se o nome aparecer entre aspas duplas, esse arquivo será localizado a partir do diretório corrente. Caso esse nome apareça entre < e >, o arquivo a ser incluído será procurado no diretório onde ficam as definições das bibliotecas padrões. Exemplos:
#include <stdio.h>
#include "calendar.h"

Para um programa poder ser executado, primeiramente cada um de seus módulos devem ser compilados a fim de gerar um arquivo objeto relocável. Os arquivos de implementação dos módulos são compilados diretamente, já os cabeçalhos indiretamente, sempre que incluídos no arquivo .C de um módulo. Todos os arquivos-objeto relocáveis (.O), resultantes da compilação de cada um dos módulos do programa devem ser ligados para gerar o que chamamos de arquivo-executável.

Compilação separada de módulos no gcc:
A opção -c do gcc indica que o módulo deve ser compilado individualmente, gerando um módulo objeto .O.
Exemplo: gcc -c calendar.c

Esse comando causa a compilação do módulo "calendar.c", gerando o arquivo objeto relocável correspondente, "calendar.o". Para compilar o módulo principal, ex: "lab06.c", que deve ser ligado ao módulo objeto "calendar.o", devemos acionar o gcc através do comando abaixo:

gcc -o lab06 calendar.o lab06.c

Nessa linha de comando, a opção "-o" está sendo usada para indicar o nome do executável gerado, o módulo objeto "calendar.o" está sendo passado como parâmetro e "lab06.c" corresponde ao módulo principal a ser compilado.

Compilação de módulos no DEV-C++:
O primeiro passo no caso do DEV-C++ é criar um novo projeto. Para isso você deve clicar em "New" e depois em "Project...". Selecione a opção "Empty Project" e marque o tipo de projeto como "C Project". Salve o projeto (.dev) na pasta que contém os arquivos com o código fonte do programa. Feito isso, no canto esquerdo você deve clicar com o botão direito do mouse sobre o nome do projeto e apertar em "Add to Project". Você deve adicionar ao projeto os arquivos .C de todos os módulos e inclusive o do módulo principal. Depois é só apertar para compilar e rodar normalmente.

Atividade:
Tomando por base o arquivo de cabeçalho fornecido abaixo você deve construir um módulo calendar contendo funções que sintetizam tudo o que foi feito até agora:

  • calendar.h: que contém os protótipos das funções.
  • calendar.c: que implementa as funções descritas no cabeçalho acima.
  • lab06.c: módulo principal que usa as funções definidas acima para imprimir o calendário.

Forma de entrega:
Não é necessário entregar esta atividade. No entanto os conceitos utilizados e a modularização do código serão exigidos nas atividades seguintes.


AVISO: Esta página não é uma publicação oficial da UNICAMP. A responsabilidade por seu conteúdo é exclusivamente do autor.
DISCLAIMER: This is a personal page, and not an official UNICAMP page. Its contents are of entire responsibility of Paulo Miranda.