Aula 24 - Pré-processador PDF

Title Aula 24 - Pré-processador
Course Algorítimos de Programação
Institution Universidade Federal de Mato Grosso do Sul
Pages 8
File Size 193.3 KB
File Type PDF
Total Downloads 79
Total Views 152

Summary

Aula 24 do curso de Algoritmos e Programação I...


Description

AULA

24

P RÉ - PROCESSADOR

O pré-processador é um módulo da linguagem C que edita um programa antes de sua compilação. É uma ferramenta poderosa e que diferencia a linguagem C das demais linguagens de programação do alto nível. As diretivas #include e #define que usamos em aulas anteriores são manipuladas pelo pré-processador, assim como outras que veremos nesta aula. Apesar de poderoso, o mal uso do pré-processador pode produzir programas praticamente ininteligíveis e/ou com erros muito difíceis de encontrar. Esta aula é baseada na referência [7].

24.1

Funcionamento

As diretivas de pré-processamento controlam o comportamento do pré-processador. Uma diretiva do pré-processador é um comando que inicia com o caractere # . Até o momento, vimos duas das diretivas do pré-processador da linguagem C: #include e #define . Revisaremos essas diretivas adiante. A figura 24.1 ilustra o papel do pré-processador durante o processo de compilação. programa na linguagem C

pre−processador

programa em C modificado

compilador

codigo objeto

Figura 24.1: O papel do pré-processador durante a compilação. 275

24 P RÉ - PROCESSADOR

276

A entrada para o pré-processador é um programa escrito na linguagem C, possivelmente contendo diretivas. O pré-processador executa então estas diretivas, eliminando-as durante este processo. A saída produzida pelo pré-processador é um outro programa na linguagem C, que representa uma versão editada do programa original, sem diretivas. A saída do préprocessador é a entrada para o compilador, que verifica erros no programa e realiza sua tradução para o código objeto, que contém apenas instruções diretas para a máquina.

24.2

Diretivas de pré-processamento

A maioria das diretivas de pré-processamento pertencem a uma das três categorias a seguir: • definição de macros: a diretiva #define define uma macro, também chamada de constante simbólica; a diretiva #undef remove a definição de uma macro; • inclusão de arquivos: a diretiva #include faz com que o conteúdo de um arquivo especificado seja incluído em um programa; • compilação condicional: as diretivas #if , #ifdef , #ifndef , #elif , #else e #endif permitem que trechos de código seja incluídos ou excluídos do programa, dependendo das condições verificadas pelo pré-processador. As outras diretivas #error , #line e #pragma são mais específicas e usadas com menos frequência. Antes de descrevê-las com mais detalhes, listamos abaixo as regras que se aplicam a todas elas: • Diretivas sempre iniciam com o símbolo # . Não é necessário que o símbolo # seja o primeiro caractere da linha. No entanto, apenas espaços podem precedê-lo. Após # o identificador de uma diretiva deve ser descrito, seguido por qualquer outra informação que a diretiva necessite. • Qualquer número de espaços e caracteres de tabulação horizontal podem separar os itens em uma diretiva. Por exemplo, a diretiva a seguir está correta: #

define

MAX

100

• Diretivas sempre terminam no primeiro caractere de mudança de linha, a menos que a continuação seja explícita. Para continuar uma diretiva em uma próxima linha, devemos finalizar a linha atual com o caractere \ . Por exemplo, a diretiva abaixo define uma macro que representa a capacidade de um disco medida em bytes:

#define CAPACIDADE_DISCO (LADOS * TRILHAS_POR_LADO * SETORES_POR_TRILHA * BYTES_POR_SETOR)

FACOM

\ \ \

UFMS

24 P RÉ - PROCESSADOR

277

• Diretivas podem aparecer em qualquer lugar em um programa. Apesar de usualmente colocarmos as diretivas #include e #define no começo de um arquivo, outras diretivas são mais prováveis de ocorrer em outros pontos do programa. • Comentários podem ocorre na mesma linha de uma diretiva. Em geral, colocamos um comentário no final da definição de uma macro para explicar seu significado. Por exemplo: #define MAXIMO 100

24.3

/* Dimensão dos vetores */

Definições de macros

O uso mais frequente da diretiva #define do pré-processador da linguagem C é a atribuição de nomes simbólicos para constantes. Macros como essas são conhecidas como macros simples. O pré-processador também suporta definição de macros parametrizadas. Nesta aula veremos apenas as macros simples. A definição de uma macro simples tem a seguinte forma:

#define identificador lista-de-troca

onde lista-de-troca é uma sequência qualquer de itens. Essa lista pode incluir identificadores, palavras reservadas, constantes numéricas, constantes de caracteres, literais, operadores e pontuação. Quando encontra uma definição de uma macro, o pré-processador toma nota que o identificador representa a lista-de-troca . Sempre que identificador ocorre posteriormente no arquivo, o pré-processador o substitui pela lista-de-troca . Um erro frequente na definição de macros é a inclusão de símbolos extras, que consequentemente farão parte da lista de troca. Abaixo são mostrados dois exemplos de erros como esse.

#define TAM = 100 #define N 10; . . . int u[TAM]; double v[N];

A tradução do trecho de código acima realizada pelo pré-processador gera o seguinte trecho de código modificado, correspondente às duas última linhas:

int u[= 100]; double v[10;];

É certo que o compilador acusará erros nessas duas linhas do programa. FACOM

UFMS

24 P RÉ - PROCESSADOR

278

Podemos usar macros para dar nomes a valores numéricos, caracteres e literais, como ilustrado abaixo: #define #define #define #define #define #define

COMPRIMENTO VERDADEIRO FALSO PI ENTER ERRO

80 1 0 3.141592 ’\n’ "Erro: memória insuficiente\n"

Usar a diretiva #define para criar nomes para constantes tem diversas vantagens, como tornar os programas mais fáceis de ler e de modificar, ajudar a evitar inconsistências e erros tipográficos, permitir pequenas mudanças na sintaxe da linguagem, renomear tipos e controlar a compilação condicional.

24.4

Inclusão de arquivos-cabeçalhos

Vamos recordar a aula 22. A diretiva #include ordena o pré-processador a abrir um arquivo especificado e a inserir seu conteúdo no arquivo atual. Assim, se queremos que vários arquivos de código fonte tenham acesso à mesma informação, devemos colocar essa informação em um arquivo e então usar a diretiva #include para trazer o conteúdo do arquivo em cada arquivo de código fonte. Arquivos que são incluídos dessa forma são chamados de arquivos-cabeçalhos, do inglês header files ou também include files. Por convenção, um arquivo como esse tem a extensão .h . A diretiva #include pode ser usada de duas formas. A primeira forma é usada para arquivos-cabeçalhos que pertencem à biblioteca padrão da linguagem C:

#include

A segunda forma é usada para todos os outros arquivos-cabeçalhos, incluindo aqueles que são escritos por programadores(as):

#include "arquivo.h"

A diferença entre as duas formas se dá pela maneira como o compilador busca o arquivocabeçalho. Na primeira, o compilador busca o arquivo-cabeçalho no(s) diretório(s) em que os arquivos-cabeçalhos do sistema se encontram. Nos sistemas baseados no UNIX , como o LINUX , os arquivos-cabeçalhos são mantidos usualmente no diretório /usr/include . Na segunda forma, a busca é realizada no diretório corrente e, em seguida, no(s) diretório(s) em que os arquivos-cabeçalhos do sistema se encontram. Arquivos-cabeçalhos auxiliam no compartilhamento de definições de macros, de tipos e de protótipos de funções por dois ou mais arquivos de código fonte. FACOM

UFMS

24 P RÉ - PROCESSADOR

279

Programa 24.1: Um programa curioso. #include #define #define #define #define #define #define #define #define #define #define #define

PAR IMPAR Algoritmo inicio fim escreva leia se senao enquanto devolva

0 1 main { } printf scanf if else while return

/* Recebe um número inteiro positivo e verifica sua paridade */ int par_impar(int numero) inicio int paridade; se (numero % 2 == 0) paridade = PAR; senao paridade = IMPAR; devolva paridade; fim /* Recebe um número inteiro n > 0 e uma sequência de n números inteiros, e imprime a soma dos pares e ímpares */ int Algoritmo(void) inicio int i, n, numero, s_par, s_impar; escreva("Informe a quantidade de elementos: "); leia("%d", &n); s_par = 0; s_impar = 0; i = 1; enquanto (i...


Similar Free PDFs