Como o nome sugere Pré-processadores são programas que processam nosso código fonte antes da compilação. Há uma série de passos envolvidos entre escrever um programa e executar um programa em C / C+++. Vamos dar uma olhada nestes passos antes de realmente começarmos a aprender sobre Pré-processadores.

Você pode ver os passos intermediários no diagrama acima. O código fonte escrito pelos programadores é armazenado no arquivo program.c. Este arquivo é então processado pelos pré-processadores e um arquivo de código fonte expandido é gerado com o nome de programa. Este arquivo expandido é compilado pelo compilador e um arquivo de código objeto é gerado com o nome de programa .obj. Finalmente, o linker liga este arquivo de código objeto ao código objeto das funções da biblioteca para gerar o arquivo executável program.exe.

Programas pré-processadores fornecem diretivas de pré-processadores que dizem ao compilador para pré-processar o código fonte antes da compilação. Todas estas diretivas de pré-processador começam com um símbolo ‘#’ (hash). O símbolo ‘#’ indica que, qualquer declaração que comece com #, vai para o programa de pré-processamento, e o programa de pré-processamento irá executar esta declaração. Exemplos de algumas diretivas do pré-processador são: #include, #define, #ifndef etc. Lembre-se que o símbolo # fornece apenas um caminho que irá para o pré-processador, e comandos como include são processados pelo programa de pré-processamento. Por exemplo, o include incluirá código extra ao seu programa. Podemos colocar estas diretivas do pré-processador em qualquer lugar do nosso programa.

Existem 4 tipos principais de diretivas de pré-processador:

>

  1. Macros
  2. Inclusão de arquivo
  3. Compilação condicional
  4. Outras diretivas

Deixe-nos agora aprender sobre cada uma destas diretivas em detalhes.

  • Macros: As macros são um pedaço de código num programa ao qual é dado algum nome. Sempre que este nome é encontrado pelo compilador, o compilador substitui o nome pelo pedaço de código real. A diretiva ‘#define’ é usada para definir uma macro. Vamos agora entender a definição da macro com a ajuda de um programa:
C++

#include <iostream>
#define LIMIT 5
int main()
{
for (int i = 0; i < LIMIT; i++) {
std::cout << i << "\n";
}
return 0;
}



C

#include <stdio.h>
#define LIMIT 5
int main()
{
for (int i = 0; i < LIMIT; i++) {
printf("%d \n",i);
}
return 0;
}



Saída:

01234

No programa acima, quando o compilador executa a palavra LIMIT ele a substitui por 5. A palavra ‘LIMIT’ na definição de macro é chamada de modelo de macro e ‘5’ é expansão de macro.

Nota: Não há nenhum ponto e vírgula(‘;’) no final da definição de macro. As definições de macro não precisam de um ponto-e-vírgula para terminar.

Macros com argumentos: Também podemos passar argumentos para as macros. Macros definidas com argumentos funcionam de forma semelhante como funções. Vamos entender isto com um programa:

C++

#include <iostream>
#define AREA(l, b) (l * b)
int main()
{
int l1 = 10, l2 = 5, area;
area = AREA(l1, l2);
std::cout << "Area of rectangle is: " << area;
return 0;
}



C

#include <stdio.h>
#define AREA(l, b) (l * b)
int main()
{
int l1 = 10, l2 = 5, area;
area = AREA(l1, l2);
printf("Area of rectangle is: %d", area);
return 0;
}



Saída:

Area of rectangle is: 50

No programa acima podemos ver que, sempre que o compilador encontra AREA(l, b) no programa ele o substitui com a declaração (l*b) . Não só isso, os valores passados para o modelo de macro AREA(l, b) também serão substituídos na instrução (l*b). Portanto, AREA(10, 5) será igual a 10*5.

  • Inclusão de arquivo: Este tipo de diretiva de pré-processador diz ao compilador para incluir um arquivo no programa de código fonte. Há dois tipos de arquivos que podem ser incluídos pelo usuário no programa:
    • Arquivo de cabeçalho ou arquivos padrão: Estes ficheiros contêm definição de funções pré-definidas como printf(), scanf(), etc. Estes ficheiros devem ser incluídos para trabalhar com estas funções. Diferentes funções são declaradas em diferentes ficheiros de cabeçalho. Por exemplo funções I/O standard estão em ficheiro ‘iostream’ enquanto que funções que executam operações string estão em ficheiro ‘string’.
      Sintaxe:
#include< file_name >

onde file_name é o nome do arquivo a ser incluído. Os parênteses ‘<‘ e ‘>’ dizem ao compilador para procurar o arquivo no diretório padrão.

>

  • ficheiros definidos pelo utilizador: Quando um programa se torna muito grande, é uma boa prática dividi-lo em arquivos menores e incluí-los sempre que necessário. Estes tipos de ficheiros são ficheiros definidos pelo utilizador. Estes arquivos podem ser incluídos como:
#include"filename"
  • Compilação Condicional: Diretrizes de Compilação Condicional são tipos de diretrizes que ajudam a compilar uma porção específica do programa ou a pular a compilação de alguma parte específica do programa com base em algumas condições. Isto pode ser feito com a ajuda de dois comandos de pré-processamento, ‘ifdef’ e ‘endif’.
    Syntax:
#ifdef macro_name statement1; statement2; statement3; . . . statementN;#endif

Se a macro com nome como ‘macroname’ estiver definida então o bloco de instruções será executado normalmente, mas se não estiver definido, o compilador simplesmente pulará este bloco de instruções.

  • Outras diretivas: Além das diretivas acima, existem mais duas diretivas que não são comumente usadas. Estas são:
    • #undef Directive: A diretiva #undef é usada para indefinir uma macro existente. Esta diretriz funciona como:
#undef LIMIT

Utilizar esta afirmação irá indefinir a macro LIMIT existente. Após esta afirmação cada afirmação “#ifdef LIMIT” será avaliada como falsa.

  • #directiva deragma: Esta diretiva é uma diretiva de propósito especial e é usada para ligar ou desligar algumas características. Este tipo de diretivas são específicas para compiladores, ou seja, elas variam de compilador para compilador. Algumas das diretivas #pragma são discutidas abaixo:
    • #pragma startup e #pragma exit: Estas diretivas nos ajudam a especificar as funções que são necessárias para executar antes da inicialização do programa( antes do controle passar para main()) e pouco antes do programa sair (pouco antes do controle retornar do main()).
      Note: Abaixo o programa não irá funcionar com compiladores GCC.
      Localize o programa abaixo:
C++

#include <bits/stdc++.h>
using namespace std;
void func1();
void func2();
#pragma startup func1
#pragma exit func2
void func1()
{
cout << "Inside func1()\n";
}
void func2()
{
cout << "Inside func2()\n";
}
int main()
{
void func1();
void func2();
cout << "Inside main()\n";
return 0;
}



C

#include <stdio.h>
void func1();
void func2();
#pragma startup func1
#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 func1()Inside main()Inside func2()

O código acima produzirá a saída como indicado abaixo quando executado em compiladores GCC:

Inside main()

Isso acontece porque o GCC não suporta #pragma startup ou exit. No entanto, você pode usar o código abaixo para uma saída similar em compiladores GCC.

C

#include <stdio.h>
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;
}



  • #pragma avisa directiva: Esta directiva é usada para ocultar a mensagem de aviso que é exibida durante a compilação.
    Podemos ocultar os avisos como mostrado abaixo:
    • #pragma warn -rvl: Esta diretiva esconde os avisos que são levantados quando uma função que é suposto retornar um valor não retorna um valor.
    • #pragma warn -par: Esta diretiva esconde aqueles avisos que são levantados quando uma função que não usa os parâmetros passados para ela.
    • #pragma warn -rch: Esta diretiva esconde aqueles avisos que são levantados quando um código é inalcançável. Por exemplo: qualquer código escrito após a declaração de retorno em uma função é inalcançável.

Este artigo é contribuído por Harsh Agarwal. Se você gosta de GeeksforGeeks e gostaria de contribuir, você também pode escrever um artigo usando contribute.geeksforgeeks.org ou enviar seu artigo por e-mail para [email protected]. Veja o artigo que aparece na página principal do GeeksforGeeks e ajude outros Geeks.

.

Deixe uma resposta

O seu endereço de email não será publicado.