A diretiva #include nome_de_arquivo faz com que o texto contido num 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 pelo compilador no diretório onde ficam as definições das bibliotecas utilizadas pelo mesmo. Exemplos:
#include <stdio.h> #include "busca.h"
No primeiro exemplo, o arquivo a ser incluído será o arquivo denominado "stdio.h", localizado no diretório onde o compilador normalmente procura as definições de biblioteca. No segundo exemplo, será incluído o arquivo "busca.h", localizado no diretóro corrente.
O compilador C não impõe nenhuma restrição quanto ao nome e nem quanto ao conteúdo dos arquivos incluídos durante a compilação. Além disso a diretiva #include pode aparecer em qualquer ponto do programa.
A experiência de uso da linguagem durante anos disseminou uma disciplina que é utilizada atualmente pela maioria dos programadores e estimulada pelas práticas padrão de programação. Essa disciplina estabelece o seguinte:
Em C, para que se possa usar uma variável, constante ou função, a mesma deve ter sido previamente definida. No caso de uma função, essa "definição" pode ser feita de duas formas:
int busca(char *, struct linha *, int); void teste(char *);
A implementação das funçõe declaradas acima poderia ser a seguinte:
int busca(char* nome, struct linha* tab, int n)
{
int cond;
int esq, dir, m;
esq = 0;
dir = n - 1;
while (esq <= dir) {
m = (esq + dir) / 2;
if((cond = strcmp(nome, tab[m].nome)) < 0) dir = m - 1;
else if(cond > 0) esq = m + 1;
else return m;
}
return -1; /* nao achou ! */
}
void teste(char* nome)
{
int b;
printf("nome: %s ramal: ",nome);
if((b = busca(nome,tabela,N))== -1) printf("desconhecido\n");
else printf(" %d \n", tabela[b].numero);
}
No exemplo apresentado a seguir, o mesmo programa de busca em tabelas é implementado através de 3 módulos:
// ==========================================
// bin.h
// =========================================
struct linha
{
char * nome;
int numero;
};
int busca(char *, struct linha *, int);
// ===========================================
// bin.c
// ==========================================
#include "bin.h"
int busca(char* nome, struct linha* tab, int n)
{
int cond;
int esq, dir, m;
esq = 0;
dir = n - 1;
while (esq <= dir) {
m = (esq + dir) / 2;
if((cond = strcmp(nome, tab[m].nome)) < 0) dir = m - 1;
else if(cond > 0) esq = m + 1;
else return m;
}
return -1; /* nao achou ! */
}
Os arquivos "tab.h" e "tab.c" contém o seguinte:
// ================================== // tab.h // ================================== extern struct linha tabela[]; int tamanho();
// =========================================
// tab.c
// =========================================
#include "bin.h"
#include "tab.h"
#define N 17
struct linha tabela[N] = {
{"Angela", 323 },
{"Antonio", 423 },
{"Beatriz", 524 },
{"Carla", 623 },
{"Carlos", 324 },
{"Denise", 624 },
{"Eduardo", 326 },
{"Fernanda", 523 },
{"Fernando", 223 },
{"Francisco",331 },
{"Giselle", 231 },
{"Heitor", 443 },
{"Ingrid", 334 },
{"Joao", 211 },
{"Jose", 324 },
{"Leticia", 536 },
{"Luis", 634 }
};
int tamanho(){ return N; }
É importante notar que no arquivo "tab.h" a variável tabela está sendo definida como extern, o que significa que a mesma deve ter sido declarada em outro módulo. Essa declaração está sendo feita em "tab.c".
O arquivo "tstbin.c", correspondente ao programa principal tem o seguinte conteúdo:
// ===================================
// tstbin.c
// ===================================
#include <string.h>
#include "bin.h"
#include "tab.h"
void teste(char *);
int main()
{
teste("Eduardo");
teste("Joao");
teste("Angela");
teste("Joaquim");
}
void teste(char* nome)
{
int b;
printf("nome: %s ramal: ",nome);
if((b = busca(nome,tabela,tamanho()))== -1) printf("desconhecido\n");
else printf(" %d \n", tabela[b].numero);
}
A opção -c do gcc indica que o programa deve apenas compilado, gerando um módulo objeto. Exemplos:
gcc -c bin.c gcc -c tab.c
Esses comandos causam a compilação dos módulos "bin.c" e "tab.c", gerando os módulos objeto correspondentes, "bin.o" e "tab.o". Para compilar o módulo principal, "tstbin.c", que deve ser ligado aos módulos objetos "bin.o" e "tab.o", devemos acionar o gcc através do comando abaixo:
gcc -o tstbin bin.o tab.o tstbin.c
Nessa linha de comando, a opção "-o" está sendo usada para indicar o nome do executável gerado, os módulos objeto "bin.o" e "tab.o" estão sendo passados como parâmetros e "tstbin.c" corresponde ao módulo principal a ser compilado.