Elementos de programação em C.pdf

April 24, 2019 | Author: Laércio Rodrigues | Category: Macro (Computer Science), C (Programming Language), Compiler, Linux, Interest
Share Embed Donate


Short Description

Download Elementos de programação em C.pdf...

Description

Elementos de programação em C Diretivas de pré-processamento

Francisco A. C. Pinheiro,   Elementos de Programação em C , Bookman, 2012. Visite Visite os sítios do livro para obter material adicional: adicional: www.bookman.c www.bookman.com. om.br br e www.fac www.facp. p.pro pro.b .br/l r/livro ivroc c

Sumário

1

Diretivas de pré-processamento pré-processamento

2

Inclusão Inclusão condiciona condicionall de código

3

4

5

  Macros predefinidas Erros de pré-p pré-processam rocessamento ento   Bibliografia

Diretivas de pré-processamento

Inclusão de arquivos

Inclusão de arquivos

#inclu #in clude de

Inclui o arquivo arquivo do sistema sistema  arqsis.

#inclu #in clude de "ar "arqusu qusu" "

Inclui o arquivo arquivo do usuário usuário  arqusu.

Diretivas de pré-processamento

Inclusão de arquivos

Inclusão de arquivos

#inclu #in clude de

Inclui o arquivo arquivo do sistema sistema  arqsis.

#inclu #in clude de "ar "arqusu qusu" "

Inclui o arquivo arquivo do usuário usuário  arqusu.

As seguintes opções modificam a ordem de pesquisa dos diretórios na busca por arquivos durante a compilação: -Idir   Coloca dir  no   no início da lista dos diretórios que são pesquisados na busca dos arquivos identificados pelas diretivas  #include. -iquotedir   Coloca dir  no   no início da lista dos diretórios que são pesquisados

na busca dos arquivos do usuário, se esses arquivos não estiverem no diretório corrente.

Diretivas de pré-processamento

Inclusão de arquivos

Inclusão de arquivos — ordem de pesquisa

Com as opções -I e  -iquote, a seguinte ordem de pesquisa é adotada: Os arquivos do sistema são pesquisados primeiro nos diretórios especificados pelas opções -I, e por último nos diretórios padrões do sistema. Os arquivos do usuário são pesquisados primeiro no diretório corrente, a seguir nos diretórios especificados pelas opções  iquote, depois nos diretórios especificados pelas opções -I, e por último nos diretórios padrões do sistema.

Diretivas de pré-processamento   Macros

Definindo constantes #define nome_macro  expressão_definidora 

Durante o pré-processamento todas as referências a macros são substituídas por sua definição. A expressão definidora de uma macro não é avaliada no processo de substituição, que é puramente textual. A expressão resultante da substituição é avaliada durante a compilação. As macros podem ser usadas na definição de outras macros: Após cada substituição o texto resultante é reanalisado e, se nele houver macros, novas substituições têm efeito. Entretanto, se em algum momento o texto resultante contém o nome da macro sendo substituída, esse nome não é mais objeto de avaliação.

Diretivas de pré-processamento   Macros

Definindo constantes Exemplo

A sequência de definições ao lado faz com que VF  seja substituída por:

# d ef in e # d e fi ne # d ef in e # d e f in e # d e fi ne # d ef in e # d ef in e

VP 50 0 A NO S 1 3 M ES ES 1 J U R OS _ PE R C 0 .6 J UR OS J UR O S_ PE R C / 1 00 P ER IO DO A NO S * 12 + M ES ES VF VP * po w ((1 + J UR OS ) , P ER IO DO )

500 * pow((1 + 0.6 / 100), 13 * 12 + 1)

Diretivas de pré-processamento   Macros

Definindo constantes Exemplo

A sequência de definições ao lado faz com que VF  seja substituída por:

# d ef in e # d e fi ne # d ef in e # d e f in e # d e fi ne # d ef in e # d ef in e

VP 50 0 A NO S 1 3 M ES ES 1 J U R OS _ PE R C 0 .6 J UR OS J UR O S_ PE R C / 1 00 P ER IO DO A NO S * 12 + M ES ES VF VP * po w ((1 + J UR OS ) , P ER IO DO )

500 * pow((1 + 0.6 / 100), 13 * 12 + 1)

VF



VP * pow((1 + JUROS), PERIODO)

Diretivas de pré-processamento   Macros

Definindo constantes Exemplo

A sequência de definições ao lado faz com que VF  seja substituída por:

# d ef in e # d e fi ne # d ef in e # d e f in e # d e fi ne # d ef in e # d ef in e

VP 50 0 A NO S 1 3 M ES ES 1 J U R OS _ PE R C 0 .6 J UR OS J UR O S_ PE R C / 1 00 P ER IO DO A NO S * 12 + M ES ES VF VP * po w ((1 + J UR OS ) , P ER IO DO )

500 * pow((1 + 0.6 / 100), 13 * 12 + 1)

VF

→ →

VP * pow((1 + JUROS), PERIODO) 500 * pow((1 + JUROS), PERIODO)

Diretivas de pré-processamento   Macros

Definindo constantes Exemplo

A sequência de definições ao lado faz com que VF  seja substituída por:

# d ef in e # d e fi ne # d ef in e # d e f in e # d e fi ne # d ef in e # d ef in e

VP 50 0 A NO S 1 3 M ES ES 1 J U R OS _ PE R C 0 .6 J UR OS J UR O S_ PE R C / 1 00 P ER IO DO A NO S * 12 + M ES ES VF VP * po w ((1 + J UR OS ) , P ER IO DO )

500 * pow((1 + 0.6 / 100), 13 * 12 + 1)

VF

→ → →

VP * pow((1 + JUROS), PERIODO) 500 * pow((1 + JUROS), PERIODO) 500 * pow((1 + JUROS_PERC / 100), PERIODO)

Diretivas de pré-processamento   Macros

Definindo constantes Exemplo

A sequência de definições ao lado faz com que VF  seja substituída por:

# d ef in e # d e fi ne # d ef in e # d e f in e # d e fi ne # d ef in e # d ef in e

VP 50 0 A NO S 1 3 M ES ES 1 J U R OS _ PE R C 0 .6 J UR OS J UR O S_ PE R C / 1 00 P ER IO DO A NO S * 12 + M ES ES VF VP * po w ((1 + J UR OS ) , P ER IO DO )

500 * pow((1 + 0.6 / 100), 13 * 12 + 1)

VF

→ → →

VP * pow((1 + JUROS), PERIODO) 500 * pow((1 + JUROS), PERIODO) 500 * pow((1 + JUROS_PERC / 100), PERIODO) e assim por diante.

Diretivas de pré-processamento

Macros parametrizadas

Simulando funções

#define nome_macro (lista_parâmetros ) expressão_definidora 

A lista de parâmetros deve vir imediatamente após o nome da macro, sem espaço entre eles. Os parâmetros são especificados entre parênteses, separados por vírgula. Os parâmetros de uma macro podem não ser usados na expressão definidora. As referências a uma macro parametrizada devem respeitar o número de parâmetros de sua definição.

Diretivas de pré-processamento

Macros parametrizadas

Simulando funções #define f(x) 2 * (x)

#define abs(val, x) if ((x) < 0) (val) = -(x); else (val) = (x)

#define g(a, x y )(a)

>

0?(a) : (x y)

#define fun(a, b, c) 2 * (a) + (b)

Diretivas de pré-processamento

Macros parametrizadas

Simulando funções #define f(x) 2 * (x) f(x + 3) → 2 * (x + 3) #define abs(val, x) if ((x) < 0) (val) = -(x); else (val) = (x)

#define g(a, x y )(a)

>

0?(a) : (x y)

#define fun(a, b, c) 2 * (a) + (b)

Diretivas de pré-processamento

Macros parametrizadas

Simulando funções #define f(x) 2 * (x) f(x + 3) → 2 * (x + 3) #define abs(val, x) if ((x) < 0) (val) = -(x); else (val) = (x) abs(&num, -2) → if ((-2) < 0) (&num) = -(-2); else (&num) = (-2) #define g(a, x y )(a)

>

0?(a) : (x y)

#define fun(a, b, c) 2 * (a) + (b)

Diretivas de pré-processamento

Macros parametrizadas

Simulando funções #define f(x) 2 * (x) f(x + 3) → 2 * (x + 3) #define abs(val, x) if ((x) < 0) (val) = -(x); else (val) = (x) abs(&num, -2) → if ((-2) < 0) (&num) = -(-2); else (&num) = (-2) #define g(a, x y )(a)

>

0?(a) : (x y)

g(x + y, 21) → (x + y) > 0 ?

(x + y) :

#define fun(a, b, c) 2 * (a) + (b)

(21).

Diretivas de pré-processamento

Macros parametrizadas

Simulando funções #define f(x) 2 * (x) f(x + 3) → 2 * (x + 3) #define abs(val, x) if ((x) < 0) (val) = -(x); else (val) = (x) abs(&num, -2) → if ((-2) < 0) (&num) = -(-2); else (&num) = (-2) #define g(a, x y )(a)

>

0?(a) : (x y)

g(x + y, 21) → (x + y) > 0 ?

(x + y) :

#define fun(a, b, c) 2 * (a) + (b) fun(2 * c, c, y) →   2 * ( 2 + c ) + ( c ).

(21).

Diretivas de pré-processamento

Macros parametrizadas

Simulando funções — argumentos variáveis

Os parâmetros variáveis são identificados por reticências na lista de parâmetros. Na referência, os argumentos que correspondem aos parâmetros variáveis (incluindo as vírgulas que os separam) são tratados como um único valor, substituindo o identificador  __VA_ARGS__.

Diretivas de pré-processamento

Macros parametrizadas

Simulando funções — argumentos variáveis

Exemplo A macro #define soma(x, ...)

x + adiciona(__VA_ARGS__)

resulta nas seguintes substituições: soma(2, 3) soma(a, b, c) soma(6, 4, x + 3, c)

Diretivas de pré-processamento

Macros parametrizadas

Simulando funções — argumentos variáveis

Exemplo A macro #define soma(x, ...)

x + adiciona(__VA_ARGS__)

resulta nas seguintes substituições: soma(2, 3) soma(a, b, c) soma(6, 4, x + 3, c)



2 + adiciona(3)

Diretivas de pré-processamento

Macros parametrizadas

Simulando funções — argumentos variáveis

Exemplo A macro #define soma(x, ...)

x + adiciona(__VA_ARGS__)

resulta nas seguintes substituições: soma(2, 3) soma(a, b, c) soma(6, 4, x + 3, c)

→ →

2 + adiciona(3) a + adiciona(b, c)

Diretivas de pré-processamento

Macros parametrizadas

Simulando funções — argumentos variáveis

Exemplo A macro #define soma(x, ...)

x + adiciona(__VA_ARGS__)

resulta nas seguintes substituições: soma(2, 3) soma(a, b, c) soma(6, 4, x + 3, c)

→ → →

2 + adiciona(3) a + adiciona(b, c) 6 + adiciona(4, x + 3, c)

Diretivas de pré-processamento

Macros parametrizadas

Representando argumentos como cadeias de caracteres

O símbolo #  é tratado como um operador de substituição literal, quando antecede o identificador de um parâmetro na definição de uma macro. Seu efeito é delimitar com aspas a expressão usada como argumento na referência à macro: a expressão arg   é transformada em "arg ".

Diretivas de pré-processamento

Macros parametrizadas

Representando argumentos como cadeias de caracteres

Exemplo A macro #define imprime(x) printf("arg " #x " = %d\n", (x))

resulta nas seguintes substituições: imprime(x) imprime(4 + a)

Diretivas de pré-processamento

Macros parametrizadas

Representando argumentos como cadeias de caracteres

Exemplo A macro #define imprime(x) printf("arg " #x " = %d\n", (x))

resulta nas seguintes substituições: imprime(x) imprime(4 + a)

−→

printf("arg ""x"" = %d\n", (x))

Diretivas de pré-processamento

Macros parametrizadas

Representando argumentos como cadeias de caracteres

Exemplo A macro #define imprime(x) printf("arg " #x " = %d\n", (x))

resulta nas seguintes substituições: imprime(x) imprime(4 + a)

−→ −→

printf("arg ""x"" = %d\n", (x)) printf("arg x = %d\n", (x))

Diretivas de pré-processamento

Macros parametrizadas

Representando argumentos como cadeias de caracteres

Exemplo A macro #define imprime(x) printf("arg " #x " = %d\n", (x))

resulta nas seguintes substituições: imprime(x)

−→ −→

printf("arg ""x"" = %d\n", (x)) printf("arg x = %d\n", (x))

imprime(4 + a)

−→

printf("arg ""4 + a"" = %d\n", (4 + a))

Diretivas de pré-processamento

Macros parametrizadas

Representando argumentos como cadeias de caracteres

Exemplo A macro #define imprime(x) printf("arg " #x " = %d\n", (x))

resulta nas seguintes substituições: imprime(x)

−→ −→

printf("arg ""x"" = %d\n", (x)) printf("arg x = %d\n", (x))

imprime(4 + a)

−→ −→

printf("arg ""4 + a"" = %d\n", (4 + a)) printf("arg 4 + a = %d\n", (4 + a))

Diretivas de pré-processamento

Macros parametrizadas

Concatenando argumentos

O operador ##  na definição de uma macro causa a concatenação do termo que o precede com o termo que o segue imediatamente: a expressão a ## b  produz ab.

Diretivas de pré-processamento

Macros parametrizadas

Concatenando argumentos Exemplo As macros #define arg(x, y, z, w) int val ## x ## y ## z = w #define imp(x,y,z) printf("val" #x #y #z " = %d\n", val ## x ## y ## z)

produzem as seguintes substituições: arg(1, 2, 3, 869); arg(1,2, ,869); arg( , , ,869); imp(1, 2, 3); imp(1,2,); imp( , , );

Diretivas de pré-processamento

Macros parametrizadas

Concatenando argumentos Exemplo As macros #define arg(x, y, z, w) int val ## x ## y ## z = w #define imp(x,y,z) printf("val" #x #y #z " = %d\n", val ## x ## y ## z)

produzem as seguintes substituições: arg(1, 2, 3, 869); arg(1,2, ,869); arg( , , ,869); imp(1, 2, 3); imp(1,2,); imp( , , );



int val123 = 869;

Diretivas de pré-processamento

Macros parametrizadas

Concatenando argumentos Exemplo As macros #define arg(x, y, z, w) int val ## x ## y ## z = w #define imp(x,y,z) printf("val" #x #y #z " = %d\n", val ## x ## y ## z)

produzem as seguintes substituições: arg(1, 2, 3, 869); arg(1,2, ,869); arg( , , ,869); imp(1, 2, 3); imp(1,2,); imp( , , );

→ →

int val123 = 869; int val12 = 869;

Diretivas de pré-processamento

Macros parametrizadas

Concatenando argumentos Exemplo As macros #define arg(x, y, z, w) int val ## x ## y ## z = w #define imp(x,y,z) printf("val" #x #y #z " = %d\n", val ## x ## y ## z)

produzem as seguintes substituições: arg(1, 2, 3, 869); arg(1,2, ,869); arg( , , ,869); imp(1, 2, 3); imp(1,2,); imp( , , );

→ → →

int val123 = 869; int val12 = 869; int val = 869;

Diretivas de pré-processamento

Macros parametrizadas

Concatenando argumentos Exemplo As macros #define arg(x, y, z, w) int val ## x ## y ## z = w #define imp(x,y,z) printf("val" #x #y #z " = %d\n", val ## x ## y ## z)

produzem as seguintes substituições: arg(1, 2, 3, 869); arg(1,2, ,869); arg( , , ,869);

→ → →

int val123 = 869; int val12 = 869; int val = 869;

imp(1, 2, 3); imp(1,2,); imp( , , );



printf("val123 = %d\n", val123);

Diretivas de pré-processamento

Macros parametrizadas

Concatenando argumentos Exemplo As macros #define arg(x, y, z, w) int val ## x ## y ## z = w #define imp(x,y,z) printf("val" #x #y #z " = %d\n", val ## x ## y ## z)

produzem as seguintes substituições: arg(1, 2, 3, 869); arg(1,2, ,869); arg( , , ,869);

→ → →

int val123 = 869; int val12 = 869; int val = 869;

imp(1, 2, 3); imp(1,2,); imp( , , );

→ →

printf("val123 = %d\n", val123); printf("val12 = %d\n", val12);

Diretivas de pré-processamento

Macros parametrizadas

Concatenando argumentos Exemplo As macros #define arg(x, y, z, w) int val ## x ## y ## z = w #define imp(x,y,z) printf("val" #x #y #z " = %d\n", val ## x ## y ## z)

produzem as seguintes substituições: arg(1, 2, 3, 869); arg(1,2, ,869); arg( , , ,869);

→ → →

int val123 = 869; int val12 = 869; int val = 869;

imp(1, 2, 3); imp(1,2,); imp( , , );

→ → →

printf("val123 = %d\n", val123); printf("val12 = %d\n", val12); printf("val = %d\n", val);

Diretivas de pré-processamento

Macros parametrizadas

Simulando funções — recomendações

Os parâmetros devem ser delimitados por parênteses #define mult(x, y) (x) * (y)

é preferível a #define mult(x, y) x * y

Diretivas de pré-processamento

Macros parametrizadas

Simulando funções — recomendações

Os parâmetros devem ser delimitados por parênteses #define mult(x, y) (x) * (y)  mult(x + 3, x + 3) →   ( x + 3 ) * ( x + 3 )

é preferível a #define mult(x, y) x * y  mult(x + 3, x + 3) → x + 3 * x + 3

Diretivas de pré-processamento

Macros parametrizadas

Simulando funções — recomendações

Deve-se evitar argumentos com efeitos colaterais #define dobro(x) (x) + (x)

é diferente de int dobro(int x) {return x + x;}

Diretivas de pré-processamento

Macros parametrizadas

Simulando funções — recomendações

Deve-se evitar argumentos com efeitos colaterais #define dobro(x) (x) + (x) x = 4; y = dobro(++x);

resulta em

x = 6 y = 12

é diferente de int dobro(int x) {return x + x;} x = 4; y = dobro(++x);

resulta em

x = 5 y = 10

Diretivas de pré-processamento

Tornando definições sem efeito

Tornando definições sem efeito

#define LINUX define a macro  LINUX #undef WINDOWS  torna sem efeito a definição da macro  LINUX

Em tempo de compilação pode-se usar as opções -D e -U  para definir e tornar as definições sem efeito: gcc -o prog prog.c -std=c99 -DLINUX -UWINDOWS

Diretivas de pré-processamento

Testando a definição de macros

Testando a definição de macros

Operador  defined A expressão defined NOME ou  defined(NOME)  resulta no valor 1 (verdadeiro), se a macro  NOME  está definida, ou no valor 0 (falso), em caso contrário.

Operador  !defined A expressão !defined NOME ou  !defined(NOME)  resulta no valor 1 (verdadeiro), se a macro  NOME  não está definida, ou no valor 0 (falso), em caso contrário.

Inclusão condicional de código

Inclusão condicional de código O comando #if  e suas variações são usados para inclusão condicional de código:

# if d ef in ed L IN UX #endif

# i f ! d e fi ne d L IN UX #else #endif

# i f ! d e fi ne d L IN UX #else # if d ef in ed M AC #endif #endif

Inclusão condicional de código

Inclusão condicional de código #ifdef #ifndef #elif #endif #endelif

é abreviação de é abreviação de é abreviação de termina os comandos termina o comando  

# i f d ef U NI X # e l if d e fi n ed W I ND O WS #endelif #endif

#if defined #if !defined #else #if #if e  #elif #elif

# i f d ef U NI X # e l if d e fi n ed W I ND O WS #endif

# i f n de f S UN # e li f d ef in ed PC # e li f d ef in ed M AC #endif

Inclusão condicional de código

Avaliação da condição

Avaliação da condição

1

2

Os identificadores que são nomes de macros definidas, e não são operandos do operador  defined, são substituídos por suas definições. As operações  defined  são avaliadas, resultando no valor 1, se a macro usada como operando está definida, ou no valor 0, em caso contrário.

3 4

Os identificadores remanescentes são substituídos por 0. A expressão resultante é avaliada. A expressão resultante deve ser uma expressão inteira constante, mas não pode conter o operador  sizeof  nem o operador de conversão de tipo.

Inclusão condicional de código

Avaliação da condição

Avaliação da condição Exemplo Para as macros ao lado, a tabela a seguir mostra como a condição da diretiva #if é avaliada.

# d e fi ne E 1 # u n de f E 2 # d ef in e E2 12 # d e fi ne E 3 # u n de f E 3 # d e fi ne E 5 L IN UX # define SUNOS 1

Antes

Após subst.

Aval

#if #if #if #if #if

#if #if #if #if #if

#if #if #if #if #if

defined E1 !defined E2 !defined E3 E2 == 3 * (2
View more...

Comments

Copyright ©2017 KUPDF Inc.
SUPPORT KUPDF