Include Guards
Parte da seção Object Oriented Programming do Journey de C da Coddy — lição 2 de 61.
Quando um arquivo de cabeçalho é incluído várias vezes em um projeto, o compilador vê as mesmas declarações repetidamente, causando erros. Isso acontece comumente quando vários arquivos incluem o mesmo cabeçalho, ou quando os cabeçalhos incluem uns aos outros. Os include guards resolvem esse problema.
Um include guard utiliza três diretivas de pré-processador para garantir que o conteúdo de um cabeçalho seja processado apenas uma vez:
// math_utils.h
#ifndef MATH_UTILS_H
#define MATH_UTILS_H
int add(int a, int b);
#endif
Veja como funciona: #ifndef MATH_UTILS_H verifica se o símbolo MATH_UTILS_H ainda não foi definido. Se não tiver sido, o pré-processador continua e o define imediatamente com #define MATH_UTILS_H. Tudo entre este ponto e #endif é incluído na compilação.
Na segunda vez que este cabeçalho é incluído, MATH_UTILS_H já está definido, então todo o bloco é ignorado. O nome da guarda é tipicamente o nome do arquivo em letras maiúsculas, com sublinhados substituindo pontos e caracteres especiais.
Todo arquivo de cabeçalho que você criar deve ter guardas de inclusão (include guards). Esta é uma prática padrão que evita erros de compilação e torna seu código seguro para ser incluído de qualquer lugar em seu projeto.
Desafio
FácilVamos proteger um arquivo de cabeçalho contra a inclusão dupla adicionando include guards. Você trabalhará com base no utilitário de saudação da lição anterior, mas desta vez garantirá que o cabeçalho seja seguro para ser incluído várias vezes.
Você criará dois arquivos:
greet.h: Seu arquivo de cabeçalho contendo a declaração da função paragreet. Desta vez, envolva todo o conteúdo com include guards usando o símboloGREET_H.main.c: Seu arquivo principal que inclui o cabeçalho, implementa a funçãogreete a chama a partir demain().
A função greet deve aceitar um parâmetro const char* para o nome e imprimir:
Hello, Alice!Seu arquivo de cabeçalho deve seguir esta estrutura:
#ifndef GREET_H
#define GREET_H
// function declaration here
#endifVocê receberá uma entrada: um nome (string).
Imprima a mensagem de saudação exatamente como mostrado no formato acima, substituindo Alice pelo nome fornecido.
Folha de consulta
Include guards evitam que arquivos de cabeçalho sejam processados várias vezes durante a compilação, o que causaria erros.
Um include guard usa três diretivas de pré-processador:
#ifndef HEADER_NAME_H
#define HEADER_NAME_H
// conteúdo do cabeçalho aqui
#endif
#ifndef verifica se um símbolo não foi definido. Se não estiver definido, o #define o define e o conteúdo é processado. Em inclusões subsequentes, o símbolo já estará definido, então todo o bloco é ignorado.
O nome do guard é tipicamente o nome do arquivo em letras maiúsculas, com sublinhados substituindo pontos e caracteres especiais.
Todo arquivo de cabeçalho deve ter include guards como prática padrão.
Experimente você mesmo
#include <stdio.h>
#include "greet.h"
// TODO: Implementar a função greet que imprime "Hello, <name>!"
int main() {
char name[100];
scanf("%s", name);
// TODO: Chamar a função greet com o name
return 0;
}
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Object Oriented Programming
1Fundamentos da Programação Modular
Arquivos de CabeçalhoInclude GuardsArquivos-FonteFunções EstáticasRecapitulação: Calculadora Modular4Encapsulamento
Conceito de Ponteiros OpacosDefinindo Structs OpacasGetters e SettersValidação em SettersRecapitulação: Caixa Secreta2Objetos e Métodos
Structs como ObjetosO Ponteiro 'Self'Const CorrectnessPonteiro vs ValorMétodos AuxiliaresRecapitulação: Point Manager5Projeto: Conta Bancária Simples
Configuração do ProjetoImplementação da Conta3Ciclo de Vida de Objetos
Padrão de ConstrutorPadrão de DestrutorInicialização na StackCópia ProfundaRecapitulação: String Wrapper6Herança via Composição
Incorporação de StructsA Regra do Primeiro MembroAcessando Membros PaiUpcastingRecapitulação: Hierarquia de Formas9Projeto: Desenhador de Formas
Visão Geral do ProjetoImplementação do Círculo