Entendendo Arquivos de Cabeçalho em C: Tipos, Uso e Boas Práticas
Um arquivo de cabeçalho é um arquivo com extensão .h que contém declarações de funções C e definições de macros para serem compartilhadas entre vários arquivos fonte. Existem dois tipos de arquivos de cabeçalho: os arquivos que o programador escreve e os arquivos que vêm com o seu compilador.
Você solicita o uso de um arquivo de cabeçalho no seu programa incluindo-o com a diretiva de pré-processamento C #include, como você viu na inclusão do arquivo de cabeçalho stdio.h, que vem junto com o seu compilador.
Incluir um arquivo de cabeçalho é igual a copiar o conteúdo do arquivo de cabeçalho, mas não fazemos isso porque seria propenso a erros e não é uma boa ideia copiar o conteúdo de um arquivo de cabeçalho nos arquivos fonte, especialmente se tivermos vários arquivos fonte em um programa.
Uma prática simples em programas C ou C++ é manter todas as constantes, macros, variáveis globais do sistema e protótipos de funções nos arquivos de cabeçalho e incluir esse arquivo de cabeçalho onde for necessário.
Sintaxe de Inclusão
Tanto os arquivos de cabeçalho do usuário quanto os do sistema são incluídos usando a diretiva de pré-processamento #include. Ela tem as duas formas a seguir:
#include <arquivo>
Esta forma é usada para arquivos de cabeçalho do sistema. Ela procura por um arquivo chamado 'arquivo' em uma lista padrão de diretórios do sistema. Você pode antecipar diretórios a esta lista com a opção -I ao compilar seu código fonte.
#include "arquivo"
Esta forma é usada para arquivos de cabeçalho do seu próprio programa. Ela procura por um arquivo chamado 'arquivo' no diretório que contém o arquivo atual. Você pode antecipar diretórios a esta lista com a opção -I ao compilar seu código fonte.
Operação de Inclusão
A diretiva #include funciona direcionando o pré-processador C a escanear o arquivo especificado como entrada antes de continuar com o restante do arquivo fonte atual. A saída do pré-processador contém a saída já gerada, seguida pela saída resultante do arquivo incluído, seguida pela saída que vem do texto após a diretiva #include. Por exemplo, se você tiver um arquivo de cabeçalho header.h como segue:
char *test (void);
e um programa principal chamado programa.c que usa o arquivo de cabeçalho, assim:
int x; #include "header.h" int main (void) { puts (test ()); } o compilador verá o mesmo fluxo de tokens como se programa.c lesse:
int x; char *test (void); int main (void) { puts (test ()); } Cabeçalhos de Inclusão Única
Se um arquivo de cabeçalho for incluído duas vezes, o compilador processará seu conteúdo duas vezes e resultará em erro. A maneira padrão de evitar isso é envolver todo o conteúdo real do arquivo em um condicional, como isto:
#ifndef ARQUIVO_CABECALHO #define ARQUIVO_CABECALHO o arquivo de cabeçalho inteiro #endif
Esta construção é comumente conhecida como wrapper #ifndef. Quando o cabeçalho é incluído novamente, o condicional será falso, porque ARQUIVO_CABECALHO está definido. O pré-processador pulará todo o conteúdo do arquivo, e o compilador não o verá duas vezes.
Inclusões Computadas
Às vezes, é necessário selecionar um dos vários arquivos de cabeçalho diferentes para ser incluído no seu programa. Por exemplo, eles podem especificar parâmetros de configuração a serem usados em diferentes tipos de sistemas operacionais. Você poderia fazer isso com uma série de condicionais da seguinte forma:
#if SISTEMA_1 # include "sistema_1.h" #elif SISTEMA_2 # include "sistema_2.h" #elif SISTEMA_3 ... #endif
Mas à medida que cresce, torna-se tedioso. Em vez disso, o pré-processador oferece a capacidade de usar um macro para o nome do cabeçalho. Isso é chamado de inclusão computada. Em vez de escrever um nome de cabeçalho como argumento direto de #include, você simplesmente coloca um nome de macro lá:
#define SISTEMA_H "sistema_1.h" ... #include SISTEMA_H
SISTEMA_H será expandido, e o pré-processador procurará por sistema_1.h como se o #include tivesse sido escrito originalmente dessa forma. SISTEMA_H poderia ser definido pelo seu Makefile com a opção -D.
Linguagem C
- Manipulação de Arquivos em C: Dominando I/O com fopen, fprintf, fread e fseek
- Python File I/O: Dominando Operações de Arquivo, Leitura, Escrita e Gerenciamento
- Dominando Operações de Arquivo em Java com java.io – Criação, Leitura, Escrita e Exclusão
- Entendendo Arquivos STL: A Espinha Dorsal da Impressão 3D
- Dominando I/O de Arquivos em Verilog: Abrir, Ler, Escrever e Fechar
- Dominando I/O de Arquivos em C: Criando, Abrindo e Gerenciando Arquivos
- Dominando I/O de Arquivos em C++: Leitura e Escrita com fstream
- Dominando I/O de Arquivos em C#: Leitura, Escrita e Gerenciamento de Streams
- Python I/O de Arquivos: Dominando Operações de Entrada e Saída
- Lima Triangular Explicada: Design, Usos e Cuidados