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.