Skip to content

Latest commit

 

History

History
160 lines (115 loc) · 6.85 KB

File metadata and controls

160 lines (115 loc) · 6.85 KB
title localeTitle
Preprocessors
Pré-processadores

Pré-processadores em C / CPP

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

Img

Você pode ver as etapas intermediárias no diagrama acima. O código fonte escrito pelos programadores é armazenado no arquivo program.c. Este arquivo é então processado por pré-processadores e um arquivo de código-fonte expandido é gerado programa nomeado. Este arquivo expandido é compilado pelo compilador e um arquivo de código de objeto é gerado chamado program.obj. Finalmente, o vinculador vincula esse arquivo de código de objeto ao código de objeto das funções de biblioteca para gerar o arquivo executável program.exe.

Os programas de pré-processador fornecem diretivas de pré-processadores que informam ao compilador para pré-processar o código-fonte antes de compilá-lo. Todas essas diretivas de pré-processador começam com um símbolo # (hash). Esse símbolo ('#') no início de uma instrução em um programa C / C ++ indica que é uma diretiva de pré-processador. Podemos colocar essas diretivas pré-processador em qualquer parte do nosso programa. Exemplos de algumas diretivas de pré-processador são: #include , #define , #ifndef etc.

Tipos de diretivas de pré-processador:

  1. Macros
  2. Inclusão de arquivos
  3. Compilação Condicional
  4. Outras diretivas

Macros:

As macros são uma parte do código em um programa que recebe algum nome. Sempre que esse nome é encontrado pelo compilador, o compilador substitui o nome pela parte real do código. A diretiva #define é usada para definir uma macro.

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

Saída:

0 1 2

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

Não deve haver ponto e vírgula (';') no final da definição macro. As definições de macro não precisam de ponto e vírgula para terminar.

Inclusão de arquivos:

Esse tipo de diretiva de pré-processador informa ao compilador para incluir um arquivo no programa de código-fonte. Existem dois tipos de arquivos que podem ser incluídos pelo usuário no programa:

  • #### Arquivos de cabeçalho ou arquivos padrão: Esses arquivos contêm a definição de funções predefinidas como printf (),… scanf () etc. Esses arquivos devem ser incluídos para trabalhar com essas funções. … Funções diferentes são declaradas em diferentes arquivos de cabeçalho. Por exemplo… as funções de E / S padrão estão no arquivo 'iostream', enquanto as funções que… executam operações de string estão no arquivo 'string'.

Sintaxe:

#include< file_name > onde file_name é o nome do arquivo a ser incluído. Os colchetes < e > dizem ao compilador para procurar o arquivo no diretório padrão.

  • #### Arquivos definidos pelo usuário: Quando um programa se torna muito grande, é recomendável dividi-lo em arquivos menores e incluir sempre que necessário. Esses tipos de arquivos são arquivos definidos pelo usuário. Esses arquivos podem ser incluídos como: … #include"filename"

Compilação Condicional:

As diretivas de compilação condicional são tipos de diretivas que ajudam a compilar uma parte específica do programa ou a pular a compilação de alguma parte específica do programa com base em algumas condições. Isso pode ser feito com a ajuda de dois comandos de pré-processamento ifdef e endif .

Sintaxe:

  ifdef macro_name 
    statement1; 
    statement2; 
    statement3; 
    . 
    . 
    . 
    statementN; 
  endif 

Se a macro com nome como 'macroname' for definida, o bloco de instruções será executado normalmente, mas se não for definido, o compilador simplesmente ignorará este bloco de instruções.

Outras diretivas:

Para além das directivas acima, existem mais duas directivas que não são normalmente utilizadas. Esses são:

  1. ##### #undef Directiva: A diretiva #undef é usada para indefinir uma macro existente. Esta diretiva funciona como:
Sintaxe:

#undef LIMIT Usando esta declaração irá indefinir a macro LIMIT existente. Após esta declaração, cada declaração #ifdef LIMIT será avaliada como falsa.

  1. ##### #pragma directiva: Esta diretiva é uma diretiva de propósito especial e é usada para ativar ou desativar alguns recursos. Esse tipo de diretivas é específico do compilador, ou seja, elas variam de compilador para compilador. Algumas das diretivas # #pragma são discutidas abaixo:
#pragma startup e #pragma exit :

Essas diretivas nos ajudam a especificar as funções necessárias para executar antes da inicialização do programa (antes que o controle passe para main ()) e logo antes da saída do programa (logo antes que o controle retorne de main ()).

#include<stdio.h> 
 void func1(); 
 void func2(); 
 #pragma startup func1 
 #pragma exit func2 
 void func1() 
 { 
    printf("Inside func1() "); 
 } 
 void func2() 
 { 
    printf("Inside func2() "); 
 } 
 int main() 
 { 
    printf("Inside main() "); 
 
    return 0; 
 } 

Saída:
Inside func1() Inside main() Inside func2()
O código acima irá produzir a saída como indicado abaixo quando executado em compiladores GCC:
Saída:
Inside main()
Isso acontece porque o GCC não suporta a inicialização ou a saída #pragma. No entanto, você pode usar o código abaixo para uma saída similar em compiladores GCC.

#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 warn directiva:

Esta diretiva é usada para ocultar a mensagem de aviso exibida durante a compilação. Podemos ocultar os avisos conforme mostrado abaixo:

#pragma warn -rvl :

Essa diretiva oculta os avisos que são gerados quando uma função que deve retornar um valor não retorna um valor.

#pragma warn -par :

Essa diretiva oculta os avisos que são gerados quando uma função não usa os parâmetros passados ​​para ela.

#pragma warn -rch :

Essa diretiva oculta os avisos que são gerados quando um código está inacessível. Por exemplo: qualquer código escrito após a declaração de retorno em uma função é inacessível.