Você está na página 1de 50

Elementos de programao em C

Diretivas de pr-processamento

Francisco A. C. Pinheiro, Elementos de Programao em C, Bookman, 2012.

Visite os stios do livro para obter material adicional: www.bookman.com.br e www.facp.pro.br/livroc

() Elementos de programao em C 1 / 26
Sumrio

1 Diretivas de pr-processamento

2 Incluso condicional de cdigo

3 Macros predefinidas

4 Erros de pr-processamento

5 Bibliografia

() Elementos de programao em C 2 / 26
Diretivas de pr-processamento Incluso de arquivos

Incluso de arquivos

#include <arqsis> Inclui o arquivo do sistema arqsis.

#include "arqusu" Inclui o arquivo do usurio arqusu.

() Elementos de programao em C 3 / 26
Diretivas de pr-processamento Incluso de arquivos

Incluso de arquivos

#include <arqsis> Inclui o arquivo do sistema arqsis.

#include "arqusu" Inclui o arquivo do usurio arqusu.

As seguintes opes modificam a ordem de pesquisa dos diretrios na


busca por arquivos durante a compilao:
-Idir Coloca dir no incio da lista dos diretrios que so pesquisados na
busca dos arquivos identificados pelas diretivas #include.
-iquotedir Coloca dir no incio da lista dos diretrios que so pesquisados
na busca dos arquivos do usurio, se esses arquivos no estiverem no
diretrio corrente.

() Elementos de programao em C 3 / 26
Diretivas de pr-processamento Incluso de arquivos

Incluso de arquivos ordem de pesquisa

Com as opes -I e -iquote, a seguinte ordem de pesquisa adotada:


Os arquivos do sistema so pesquisados primeiro nos diretrios
especificados pelas opes -I, e por ltimo nos diretrios padres do
sistema.
Os arquivos do usurio so pesquisados primeiro no diretrio corrente,
a seguir nos diretrios especificados pelas opes iquote, depois nos
diretrios especificados pelas opes -I, e por ltimo nos diretrios
padres do sistema.

() Elementos de programao em C 4 / 26
Diretivas de pr-processamento Macros

Definindo constantes

#define hnome_macroi hexpresso_definidorai

Durante o pr-processamento todas as referncias a macros so


substitudas por sua definio.
A expresso definidora de uma macro no avaliada no processo de
substituio, que puramente textual.
A expresso resultante da substituio avaliada durante a
compilao.
As macros podem ser usadas na definio de outras macros:
Aps cada substituio o texto resultante reanalisado e, se nele
houver macros, novas substituies tm efeito.
Entretanto, se em algum momento o texto resultante contm o nome
da macro sendo substituda, esse nome no mais objeto de avaliao.

() Elementos de programao em C 5 / 26
Diretivas de pr-processamento Macros

Definindo constantes

Exemplo

# define VP 500
# define ANOS 13
A sequncia de # define MESES 1
definies ao lado faz # define JUROS_PERC 0.6
# define JUROS JUROS_PERC / 100
com que VF seja # define PERIODO ANOS * 12 + MESES
substituda por: # define VF VP * pow ((1 + JUROS ) , PERIODO )

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

() Elementos de programao em C 6 / 26
Diretivas de pr-processamento Macros

Definindo constantes

Exemplo

# define VP 500
# define ANOS 13
A sequncia de # define MESES 1
definies ao lado faz # define JUROS_PERC 0.6
# define JUROS JUROS_PERC / 100
com que VF seja # define PERIODO ANOS * 12 + MESES
substituda por: # define VF VP * pow ((1 + JUROS ) , PERIODO )

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

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

() Elementos de programao em C 6 / 26
Diretivas de pr-processamento Macros

Definindo constantes

Exemplo

# define VP 500
# define ANOS 13
A sequncia de # define MESES 1
definies ao lado faz # define JUROS_PERC 0.6
# define JUROS JUROS_PERC / 100
com que VF seja # define PERIODO ANOS * 12 + MESES
substituda por: # define VF VP * pow ((1 + JUROS ) , PERIODO )

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

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


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

() Elementos de programao em C 6 / 26
Diretivas de pr-processamento Macros

Definindo constantes

Exemplo

# define VP 500
# define ANOS 13
A sequncia de # define MESES 1
definies ao lado faz # define JUROS_PERC 0.6
# define JUROS JUROS_PERC / 100
com que VF seja # define PERIODO ANOS * 12 + MESES
substituda por: # define VF VP * pow ((1 + JUROS ) , PERIODO )

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)

() Elementos de programao em C 6 / 26
Diretivas de pr-processamento Macros

Definindo constantes

Exemplo

# define VP 500
# define ANOS 13
A sequncia de # define MESES 1
definies ao lado faz # define JUROS_PERC 0.6
# define JUROS JUROS_PERC / 100
com que VF seja # define PERIODO ANOS * 12 + MESES
substituda por: # define VF VP * pow ((1 + JUROS ) , PERIODO )

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.

() Elementos de programao em C 6 / 26
Diretivas de pr-processamento Macros parametrizadas

Simulando funes

#define hnome_macroi(hlista_parmetrosi) hexpresso_definidorai

A lista de parmetros deve vir imediatamente aps o nome da macro,


sem espao entre eles.
Os parmetros so especificados entre parnteses, separados por
vrgula.
Os parmetros de uma macro podem no ser usados na expresso
definidora.
As referncias a uma macro parametrizada devem respeitar o nmero
de parmetros de sua definio.

() Elementos de programao em C 7 / 26
Diretivas de pr-processamento Macros parametrizadas

Simulando funes

#define f(x) 2 * (x)

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

#define g(a, xy )(a) > 0?(a) : (xy)

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

() Elementos de programao em C 8 / 26
Diretivas de pr-processamento Macros parametrizadas

Simulando funes

#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, xy )(a) > 0?(a) : (xy)

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

() Elementos de programao em C 8 / 26
Diretivas de pr-processamento Macros parametrizadas

Simulando funes

#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, xy )(a) > 0?(a) : (xy)

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

() Elementos de programao em C 8 / 26
Diretivas de pr-processamento Macros parametrizadas

Simulando funes

#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, xy )(a) > 0?(a) : (xy)


g(x + y, 21) (x + y) > 0 ? (x + y) : (21).

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

() Elementos de programao em C 8 / 26
Diretivas de pr-processamento Macros parametrizadas

Simulando funes

#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, xy )(a) > 0?(a) : (xy)


g(x + y, 21) (x + y) > 0 ? (x + y) : (21).

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


fun(2 * c, c, y) 2 * (2 + c) + (c).

() Elementos de programao em C 8 / 26
Diretivas de pr-processamento Macros parametrizadas

Simulando funes argumentos variveis

Os parmetros variveis so identificados por reticncias na lista de


parmetros.
Na referncia, os argumentos que correspondem aos parmetros
variveis (incluindo as vrgulas que os separam) so tratados como um
nico valor, substituindo o identificador __VA_ARGS__.

() Elementos de programao em C 9 / 26
Diretivas de pr-processamento Macros parametrizadas

Simulando funes argumentos variveis

Exemplo
A macro
#define soma(x, ...) x + adiciona(__VA_ARGS__)
resulta nas seguintes substituies:

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

() Elementos de programao em C 10 / 26
Diretivas de pr-processamento Macros parametrizadas

Simulando funes argumentos variveis

Exemplo
A macro
#define soma(x, ...) x + adiciona(__VA_ARGS__)
resulta nas seguintes substituies:

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

() Elementos de programao em C 10 / 26
Diretivas de pr-processamento Macros parametrizadas

Simulando funes argumentos variveis

Exemplo
A macro
#define soma(x, ...) x + adiciona(__VA_ARGS__)
resulta nas seguintes substituies:

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

() Elementos de programao em C 10 / 26
Diretivas de pr-processamento Macros parametrizadas

Simulando funes argumentos variveis

Exemplo
A macro
#define soma(x, ...) x + adiciona(__VA_ARGS__)
resulta nas seguintes substituies:

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

() Elementos de programao em C 10 / 26
Diretivas de pr-processamento Macros parametrizadas

Representando argumentos como cadeias de caracteres

O smbolo # tratado como um operador de substituio literal,


quando antecede o identificador de um parmetro na definio de uma
macro.
Seu efeito delimitar com aspas a expresso usada como argumento
na referncia macro:
a expresso harg i transformada em "harg i".

() Elementos de programao em C 11 / 26
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 substituies:

imprime(x)

imprime(4 + a)

() Elementos de programao em C 12 / 26
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 substituies:

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

imprime(4 + a)

() Elementos de programao em C 12 / 26
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 substituies:

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


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

() Elementos de programao em C 12 / 26
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 substituies:

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))

() Elementos de programao em C 12 / 26
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 substituies:

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))

() Elementos de programao em C 12 / 26
Diretivas de pr-processamento Macros parametrizadas

Concatenando argumentos

O operador ## na definio de uma macro causa a concatenao do termo


que o precede com o termo que o segue imediatamente:
a expresso a ## b produz ab.

() Elementos de programao em C 13 / 26
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 substituies:

arg(1, 2, 3, 869);
arg(1,2, ,869);
arg( , , ,869);

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

() Elementos de programao em C 14 / 26
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 substituies:

arg(1, 2, 3, 869); int val123 = 869;


arg(1,2, ,869);
arg( , , ,869);

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

() Elementos de programao em C 14 / 26
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 substituies:

arg(1, 2, 3, 869); int val123 = 869;


arg(1,2, ,869); int val12 = 869;
arg( , , ,869);

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

() Elementos de programao em C 14 / 26
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 substituies:

arg(1, 2, 3, 869); int val123 = 869;


arg(1,2, ,869); int val12 = 869;
arg( , , ,869); int val = 869;

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

() Elementos de programao em C 14 / 26
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 substituies:

arg(1, 2, 3, 869); int val123 = 869;


arg(1,2, ,869); int val12 = 869;
arg( , , ,869); int val = 869;

imp(1, 2, 3); printf("val123 = %d\n", val123);


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

() Elementos de programao em C 14 / 26
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 substituies:

arg(1, 2, 3, 869); int val123 = 869;


arg(1,2, ,869); int val12 = 869;
arg( , , ,869); int val = 869;

imp(1, 2, 3); printf("val123 = %d\n", val123);


imp(1,2,); printf("val12 = %d\n", val12);
imp( , , );

() Elementos de programao em C 14 / 26
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 substituies:

arg(1, 2, 3, 869); int val123 = 869;


arg(1,2, ,869); int val12 = 869;
arg( , , ,869); int val = 869;

imp(1, 2, 3); printf("val123 = %d\n", val123);


imp(1,2,); printf("val12 = %d\n", val12);
imp( , , ); printf("val = %d\n", val);

() Elementos de programao em C 14 / 26
Diretivas de pr-processamento Macros parametrizadas

Simulando funes recomendaes

Os parmetros devem ser delimitados por parnteses


#define mult(x, y) (x) * (y)

prefervel a
#define mult(x, y) x * y

() Elementos de programao em C 15 / 26
Diretivas de pr-processamento Macros parametrizadas

Simulando funes recomendaes

Os parmetros devem ser delimitados por parnteses


#define mult(x, y) (x) * (y)
mult(x + 3, x + 3) (x + 3) * (x + 3)

prefervel a
#define mult(x, y) x * y
mult(x + 3, x + 3) x + 3 * x + 3

() Elementos de programao em C 15 / 26
Diretivas de pr-processamento Macros parametrizadas

Simulando funes recomendaes

Deve-se evitar argumentos com efeitos colaterais


#define dobro(x) (x) + (x)

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

() Elementos de programao em C 16 / 26
Diretivas de pr-processamento Macros parametrizadas

Simulando funes recomendaes

Deve-se evitar argumentos com efeitos colaterais


#define dobro(x) (x) + (x)
x = 4; resulta em x = 6
y = dobro(++x); y = 12

diferente de
int dobro(int x) {return x + x;}
x = 4; resulta em x = 5
y = dobro(++x); y = 10

() Elementos de programao em C 16 / 26
Diretivas de pr-processamento Tornando definies sem efeito

Tornando definies sem efeito

#define LINUX define a macro LINUX


#undef WINDOWS torna sem efeito a definio da macro LINUX
Em tempo de compilao pode-se usar as opes -D e -U para definir
e tornar as definies sem efeito:
gcc -o prog prog.c -std=c99 -DLINUX -UWINDOWS

() Elementos de programao em C 17 / 26
Diretivas de pr-processamento Testando a definio de macros

Testando a definio de macros

Operador defined
A expresso defined NOME ou defined(NOME) resulta
no valor 1 (verdadeiro), se a macro NOME est definida,
ou no valor 0 (falso), em caso contrrio.

Operador !defined
A expresso !defined NOME ou !defined(NOME) resulta
no valor 1 (verdadeiro), se a macro NOME no est definida, ou
no valor 0 (falso), em caso contrrio.

() Elementos de programao em C 18 / 26
Incluso condicional de cdigo

Incluso condicional de cdigo

O comando #if e suas variaes so usados para incluso condicional de


cdigo:

# if defined LINUX # if ! defined LINUX # if ! defined LINUX


< texto -1 > < texto -1 > < texto -1 >
# endif # else # else
< texto -2 > < texto -2 > < texto -2 >
# endif # if defined MAC
< texto -3 > < texto -3 >
# endif
# endif
< texto -4 >

() Elementos de programao em C 19 / 26
Incluso condicional de cdigo

Incluso condicional de cdigo

#ifdef abreviao de #if defined


#ifndef abreviao de #if !defined
#elif abreviao de #else #if
#endif termina os comandos #if e #elif
#endelif termina o comando #elif

# ifdef UNIX # ifdef UNIX # ifndef SUN


< texto -1 > < texto -1 > < texto -1 >
# elif defined WINDOWS # elif defined WINDOWS # elif defined PC
< texto -2 > < texto -2 > < texto -2 >
# endelif # endif # elif defined MAC
# endif < texto -3 > < texto -3 >
< texto -3 > # endif
< texto -4 >

() Elementos de programao em C 20 / 26
Incluso condicional de cdigo Avaliao da condio

Avaliao da condio

1 Os identificadores que so nomes de macros definidas, e no so


operandos do operador defined, so substitudos por suas definies.
2 As operaes defined so avaliadas, resultando
no valor 1, se a macro usada como operando est definida, ou
no valor 0, em caso contrrio.
3 Os identificadores remanescentes so substitudos por 0.
4 A expresso resultante avaliada.
A expresso resultante deve ser uma expresso inteira constante, mas
no pode conter o operador sizeof nem o operador de converso de
tipo.

() Elementos de programao em C 21 / 26
Incluso condicional de cdigo Avaliao da condio

Avaliao da condio

Exemplo
Para as macros ao lado, a tabela a seguir # define E1
mostra como a condio da diretiva #if # undef E2
avaliada. # define E2 12
# define E3
# undef E3
# define E5 LINUX
# define SUNOS 1

Antes Aps subst. Aval


#if defined E1 #if defined E1 #if 1 E1 est definida.
#if !defined E2 #if !defined E2 #if 0 E2 est definida.
#if !defined E3 #if !defined E3 #if 1 E3 no est definida.
#if E2 == 3 * (2<<1) #if 12 == 3 * (2<<1) #if 1 E2 substituda por 12.
#if (E5 == SUNOS) #if (0 == 1) #if 0 E5 substituda por LINUX,
LINUX substituda por 0,
SUNOS substituda por 1.

() Elementos de programao em C 22 / 26
Macros predefinidas

Algumas macros predefinida

Macro Definio
__DATE__ Data do pr-processamento da unidade de compilao
__TIME__ Hora do pr-processamento da unidade de compilao
__FILE__ Nome do arquivo em que utilizada.
__func__ Nome da funo em que utilizada
(no , de fato, uma macro).
__FUNCTION__ Nome da funo em que utilizada (extenso do gcc).
__LINE__ Nmero da linha do arquivo-fonte na qual ocorre
a referncia macro.

() Elementos de programao em C 23 / 26
Macros predefinidas

Algumas macros predefinida

Exemplo
printf (" erro : arquivo %s , linha % d .\ n " ,
arq , linha );
/* codigo omitido */
}

A funo mostra_erro pode ser chamada com o nome do arquivo e a


linha em que ocorreu o erro:
mostra_erro(__FILE__, __LINE__)

() Elementos de programao em C 24 / 26
Erros de pr-processamento

Erros de pr-processamento

Exemplo
No trecho de programa a seguir, se a macro QTD for menor ou igual a 20, a
compilao interrompida na fase de pr-processamento produzindo uma
mensagem de erro que inclui o texto tamanho QTD invalido.

# if QTD > 20
int vet [ QTD ];
# else
# error tamanho QTD invalido
# endif

() Elementos de programao em C 25 / 26
Bibliografia

Bibliografia

ISO/IEC
C Programming Language Standard
ISO/IEC 9899:2011, International Organization for Standardization;
International Electrotechnical Commission, 3rd edition, WG14/N1570
Committee final draft, abril de 2011.
Francisco A. C. Pinheiro
Elementos de programao em C
Bookman, Porto Alegre, 2012.
www.bookman.com.br, www.facp.pro.br/livroc

() Elementos de programao em C 26 / 26