Pré-processadores são programas que processam o código-fonte antes do início da compilação real. Eles não fazem parte do processo de compilação, mas operam separadamente, permitindo que os programadores modifiquem o código antes da compilação.
- É a primeira etapa que o código-fonte C passa ao ser convertido em um arquivo executável.
- Os principais tipos de diretivas de pré-processador são Macros Compilação condicional de inclusão de arquivos e outras diretivas como #undef #pragma etc.
- Principalmente essas diretivas são usadas para substituir uma determinada seção do código C por outro código C. Por exemplo, se escrevermos '#define PI 3.14', então PI será substituído por 3.14 pelo pré-processador.
Tipos de pré-processadores C
Todos os pré-processadores acima podem ser classificados em 4 tipos:
Macros
Macros são usados para definir constantes ou criar funções que são substituídas pelo pré-processador antes da compilação do código. Os dois pré-processadores #definir e #undef são usados para criar e remover macros em C.
#definir valor simbólico
#undef ficha
onde depois de pré-processar o ficha será ampliado para o seu valor no programa.
Exemplo:
C#include // Macro Definition #define LIMIT 5 int main(){ for (int i = 0; i < LIMIT; i++) { printf('%d n' i); } return 0; }
Saída
0 1 2 3 4
No programa acima, antes do início da compilação, a palavra LIMIT é substituída por 5. A palavra 'LIMITE' na definição macro é chamado de modelo de macro e '5' é expansão macro.
Observação Não há ponto e vírgula (;) no final da definição da macro. As definições de macro não precisam de ponto e vírgula para terminar.
Existem também alguns Macros predefinidas em C que são úteis para fornecer diversas funcionalidades ao nosso programa.
Uma macro definida anteriormente pode ser indefinida usando o pré-processador #undef. Por exemplo no código acima
C#include // Macro Definition #define LIMIT 5 // Undefine macro #undef LIMIT int main(){ for (int i = 0; i < LIMIT; i++) { printf('%d n' i); } return 0; }
Saída:
./Solution.c: In function 'main': ./Solution.c:13:28: error: 'MAX' undeclared (first use in this function) printf('MAX is: %dn' MAX); ^ ./Solution.c:13:28: note: each undeclared identifier is reported only once for each function it appears inMacros com argumentos
Também podemos passar argumentos para macros. Essas macros funcionam de forma semelhante às funções. Por exemplo
inteiro para string java
# definir foo(a-b) a + b
#define função(r) r * r
Vamos entender isso com um programa:
C#include // macro with parameter #define AREA(l b) (l * b) int main(){ int a = 10 b = 5; // Finding area using above macro printf('%d' AREA(a b)); return 0; }
Saída
Area of rectangle is: 50
Explicação: No programa acima a macro ÁREA(l b) é definido para calcular a área de um retângulo multiplicando seu comprimento (l) e largura (b) . Quando ÁREA (a b) é chamado, ele se expande para (a*b) e o resultado é calculado e impresso.
Por favor consulte Tipos de macros em C para mais exemplos e tipos.
Inclusão de arquivo
A inclusão de arquivos permite incluir arquivos externos (bibliotecas de arquivos de cabeçalho, etc.) no programa atual. Isso normalmente é feito usando o #incluir diretiva que pode incluir arquivos do sistema e arquivos definidos pelo usuário.
Sintaxe
melhor automóvel do mundo
Existem duas maneiras de incluir arquivos de cabeçalho.
#incluir
#incluir 'nome do arquivo'
O '<' e '>' colchetes diga ao compilador para procurar o arquivo no diretório padrão enquanto aspas duplas (' ') diga ao compilador para procurar o arquivo de cabeçalho no diretório do arquivo de origem.
Exemplo:
C// Includes the standard I/O library #include int main() { printf('Hello World'); return 0; }
Saída
Hello World
Compilação Condicional
Compilação condicional permite incluir ou excluir partes do código dependendo de certas condições. Isso é útil para criar código específico da plataforma ou para depuração. Existem as seguintes diretivas de pré-processador condicional: #if #ifdef #ifndef else #elif e #endif
Sintaxe
A sintaxe geral dos pré-processadores condicionais é:
#se
// algum código
#elif
//mais algum código
#outro
// Mais um pouco de código
#endif
A diretiva #endif é usada para fechar as diretivas de abertura #if #ifdef e #ifndef.
Exemplo
C#include // Defining a macro for PI #define PI 3.14159 int main(){ // Check if PI is defined using #ifdef #ifdef PI printf('PI is definedn'); // If PI is not defined check if SQUARE is defined #elif defined(SQUARE) printf('Square is definedn'); // If neither PI nor SQUARE is defined trigger an error #else #error 'Neither PI nor SQUARE is defined' #endif // Check if SQUARE is not defined using #ifndef #ifndef SQUARE printf('Square is not defined'); // If SQUARE is defined print that it is defined #else printf('Square is defined'); #endif return 0; }
Saída
PI is defined Square is not defined
Explicação: Este código usa diretivas de pré-processador condicionais ( #ifdef #elif e #ifndef ) para verificar se determinadas macros ( PI e QUADRADO ) são definidos. Como PI está definido, o programa imprime ' PI é definido ' então verifica se SQUARE não está definido e imprime ' O quadrado não está definido '.
Outras Diretivas
Além das diretivas primárias do pré-processador, C também fornece outras diretivas para gerenciar o comportamento e a depuração do compilador.
o que é mac os
#pragma:
Fornece instruções específicas ao compilador para controlar seu comportamento. É usado para desativar o alinhamento do conjunto de avisos, etc.
Sintaxe
#pragma diretiva
Algumas das diretivas #pragma são discutidas abaixo:
- #pragma inicialização: Estas diretivas nos ajudam a especificar as funções que são necessárias para serem executadas antes da inicialização do programa (antes do controle passar para main()).
- #pragma saída : Essas diretivas nos ajudam a especificar as funções que são necessárias para serem executadas logo antes da saída do programa (logo antes do controle retornar de main()).
Exemplo
C#include void func1(); void func2(); // specifying funct1 to execute at start #pragma startup func1 // specifying funct2 to execute before end #pragma exit func2 void func1() { printf('Inside func1()n'); } void func2() { printf('Inside func2()n'); } int main(){ void func1(); void func2(); printf('Inside main()n'); return 0; }
Saída
Inside main()
O código acima produzirá a saída fornecida acima quando executado em compiladores GCC enquanto a saída esperada era:
Resultado Esperado
Inside func1() Inside main() Inside func2() Isso acontece porque o GCC não suporta inicialização ou saída #pragma. No entanto, você pode usar o código abaixo para a saída esperada nos compiladores GCC.
C#include void func1(); void func2(); void __attribute__((constructor)) func1(); void __attribute__((destructor)) func2(); void func1() { printf('Inside func1()n'); } void func2() { printf('Inside func2()n'); } int main() { printf('Inside main()n'); return 0; }
Saída
Inside func1() Inside main() Inside func2()
No programa acima usamos alguns sintaxes específicas para que uma das funções seja executada antes da função principal e a outra seja executada após a função principal.
Criar questionário