Anda di halaman 1dari 290

1

Prof. Elda Regina


elda_etec@hotmail.com
Fevereiro/2011
Linguagem C
2
Introduo
3
Introduo
C - Dennis Ritchie (Laboratrios Bell)
Inicialmente para mquinas do tipo PDP-1
(com UNIX).
Depois para os IBM PC e compatveis
(ambientes MS DOS, e MS Windows)
4
O Standard ANSI-C
Verso C que segue a norma da American
National Standard Institute (ANSI), e da
International Standards Organization (ISO).
Os Compiladores da Borland foram os
primeiros a oferecer compatibilidade com
esta norma (os compiladores de Turbo C a
partir da verso 2.0).
5
Caractersticas
A linguagem C muito famosa e muito
utilizada:
pela conciso de suas instrues;
pela facilidade de desenvolvimento
de Compiladores C;
pela rapidez de execuo de programas;
e principalmente pelo fato que o poderoso
sistema operacional Unix foi escrito em C.
6
Um Programa Simples
#include <stdio.h>
/*
um programa bem simples
que imprima: Ate logo.
*/
void main ()
{
printf("Ate logo. ");
}
7
Exemplo 1
#include <stdio.h> /* 1 */
#define B 20 /* 2 */
int a,s; /* 3 */
int somar (int x, int y) /* 4 */
{
return (x+y);
}
void main () /* 5 */
{
scanf("%d",&a); /* 6 */
s=somar(a,B); /* 7 */
printf("%d",s); /* 8 */
}
8
Comentrios Ex1
/* 1 */ incluso de um arquivo da biblioteca de C que
implementa as funes printf, scanf...
/* 2 */ b deve ser substitudo por 20
/* 3 */ declarao de duas variveis inteiras: a e s
/* 4 */ definio de uma funo somar
/* 5 */ definio da funo principal: main
/* 6 */ leitura do valor de a entrado pelo usurio
/* 7 */ chamada da funo somar com argumentos a e b
/* 8 */ impresso do resultado s da soma de a e b
9
Estrutura de um Programa C
Um conjunto de funes
A funo principal main
obrigatria.
A funo main o ponto de
entrada principal do programa.
10
main
void main ()
{
declaraes
instrues 1
instrues 2
...
instrues n
}
11
As outras funes
Tipo nome (declarao-de-parmetros)
{
declaraes;
instrues 1;
instrues 2;
...
instrues n;
}
12
Consideraes sobre as funes
O tipo da funo = tipo do valor que a
funo retorna
Ele pode ser predefinido, ou definido
pelo usurio.
Por default o tipo de uma funo
int.
13
Compilao
Pre-Processadores:
Transformao lexical do texto do programa.
Compiladores:
Traduo do texto gerado pelo pre-processador e
sua transformao em instrues da mquina.
Observao
Geralmente, o pre-processador considerado como
fazendo parte integrante do compilador.
14
Tipos Bsicos
15
Principais tipos de Dados
int famlia dos nmeros inteiros
float famlia dos nmeros ponto-
double flutuantes (pseudo-reais)
char famlia dos caracteres
Observao: No tem o tipo Boolean!
16
Inteiros
Podem receber dois atributos:
de preciso (para o tamanho)
de representao (para
o sinal)
Atributos de preciso:
short int : representao sobre 1 byte
int : representao sobre 1 ou
2 palavra(s)
long int : representao sobre 2
palavras
17
Inteiros
Atributos de representao
unsigned : somente os positivos
signed : positivos e negativos
18
Combinao de Atributos - Inteiros
unsigned short int : rep. sobre 8
bits [0, 255]
signed short int : rep. sobre 7 bits
[-128, 127]
unsigned int : rep. sobre 16 bits
[0, 65535]
signed int : rep. sobre 15 bits
[-32768, 32767]
unsigned long int : rep. sobre 32 bits
[0, 4294967295]
signed long int : rep. sobre 31 bits
[-2147483648, 2147483647]
19
Os Inteiros
Em Resumo, temos seis tipos de
inteiros:
int;
short int; todos signed
long int;
e
unsigned int;
unsigned short int;
unsigned long int;
20
Pseudo-Reais
(representao da forma: M * 10
EXP
)
Os flutuantes podem ser:
float :representao sobre 7 algarismos
[-3.4*10
-38
, 3.4*10
38
]
double :representao sobre 15 algarismos
[-1.7*10
-308
, 1.7*10
308
]
long double : representao sobre 19
algarismos [-3.4*10
-4932
, 3.4*10
4932
]
21
Caracteres
Um caracter representado por
seu cdigo ASCII (cdigo numrico).
Ele pode ser manipulado como um inteiro.
Um caracter codificado sobre um byte
podemos representar at 256
caracteres.
22
Caracteres
O tipo : Char
char c,b;
c = \65;
b = c;
23
E o tipo String?
No existe em C o tipo string
propriamente dito.
Um substituo:
os vetores de caracteres:
char nome[20]
24
E o tipo Boolean?
Ateno:
O Boolean no existe em C!
Isto geralmente substitudo pelo
tipo int:
0 : false
1 : true
25
Em sistemas 32 bits
char 1 -128 a 127
signed char 1 -128 a 127
unsigned char 1 0 a 255
short 2 -32,768 a 32,767
unsigned short 2 0 a 65,535
int 4 -2,147,483,648 a 2,147,483,647
unsigned int 4 0 a 4,294,967,295
long 4 -2,147,483,648 a 2,147,483,647
unsigned long 4 0 a 4,294,967,295
float 4 3.4E+/-38 (7 dgitos)
double 8 1.7E+/-308 (15 dgitos)
long double 10 1.2E+/-4932 (19 dgitos)
26
DECLARAO DE
VARIVEIS
27
Identificadores
Um identificador um meio para
manipulao da informao
Um nome que indica uma varivel,
funo, tipo de dados, etc.
28
Identificadores
Formado por uma combinao de
caracteres alfanumricos
Comea por uma letra do alfabeto ou
um sublinhado, e o resto pode ser
qualquer letra do alfabeto, ou
qualquer dgito numrico (algarismo),
ou um sublinhado.
29
Exemplos de identificadores
Exemplo:
nome_1; _a; Nota; nota;
imposto_de_renda;
!x; 4_nota;
Ateno:
Os identificadores Nota e nota por
exemplo representam duas variveis
diferentes.
30
Regras para a nomeao
Como os compiladores ANSI usam
variveis que comeam por um
sublinhado, melhor ento no us-las.
De acordo com o standard ANSI-C:
somente 32 caracteres podem ser
considerados pelos compiladores, os
outros so ignorados.
No usar as palavras chaves da
linguagem.
31
Palavras Chaves
(so 32 palavras)
auto double int struct
break else long switch
case enum register typedef
char extern return union
const float short unsigned
continue for signed void
default goto sizeof volatile
do if static while
32
Declaraes
tipo lista-de-nomes-de-variveis
Exemplo:
int i,a;
double d1, d2;
char c;
33
Inicializao de Variveis
C no inicializa automaticamente
suas variveis.
Isto pode ser feito no momento da
declarao:
int i=1,j=2, k=somar(4,5);
short int l=1; char c=\0;
34
Operaes
35
Atribuio
Exemplo:
i=4;
a=5*2;
d=-b/a;
raiz=sqrt(d);
36
Exemplos de Atribuio
i = (j = k) - 2; (caso k=5)
5 j=5
3 i=3
Atribuio mltipla:
a=b=c=8;
37
Converso de Tipos (1)
O compilador faz uma converso
automtica
float r1,r2=3.5; int i1,i2=5;
char c1,c2=A;
r1=i2; /* r1 5.0 */
i1=r2; /* i1 3 */
i1=c2; /* i1 65 */
c1=i2; /* c1 5 */
r1=c2; /* r1 65.0 */
c1=r2; /* c1 3 */
38
Converso de Tipos (2)
int a = 2;
float x = 17.1, y = 8.95, z;
char c;
c = (char)a + (char)x;
c = (char)(a + (int)x);
c = (char)(a + x);
c = a + x;
z = (float)((int)x * (int)y);
z = (float)((int)(x * y));
z = x * y;
39
Adio/subtrao/multiplicao
Expresso
1
+ expresso
2
Expresso
1
- expresso
2
Expresso
1
* expresso
2
As duas expresses so avaliadas,
depois a adio/subtrao/multiplicao
realizada, e o valor obtido o valor da
expresso.
Pode ter uma converso de tipos, depois da
avaliao das expresses:
float x,y; int z; x=y+z;
40
Diviso (1)
Expresso
1
/ expresso
2
Em C, o / designa no mesmo tempo
a diviso dos inteiros e dos reais.
Isto depende ento dos valores
retornados pelas expresses:
Se os dois so inteiros ento a diviso
inteira, mas se um deles real ento
a diviso real.
41
Diviso (2)
Caso os dois operandos inteiros so
positivos, o sistema arredonda o
resultado da diviso a zero:
7 / 2 retorna 3
Caso os dois operandos inteiros so de
sinais diferentes, o arredondamento
depende da implementao mas
geralmente feito a zero:
-7 / 2 ou 7 / -2
retornam -3 ou -4 (mas geralmente -4)
42
O Mdulo %
Expresso
1
% Expresso
2
Retorna o resto da diviso inteira.
7 % 2 retorna 1
Caso um dois operadores seja negativo, o
sinal do mdulo depende da
implementao, mas
geralmente o sinal do primeiro
7 % 2 retornam 1
-7 % 2 retornam -1
7 % -2 retornam 1
43
Operadores Relacionais
Expresso
1
op-rel Expresso
2
Onde op-rel um dos seguintes smbolos:
Operador Semntica
= = igual
!= diferentes
> superior
>= superior ou igual
< inferior
<= inferior ou igual
O resultado da comparao um valor lgico:
1 (se a comparao verificada) e 0 (seno)
44
Operadores Lgicos
Para combinar expresses lgicas
Operador Semntica
&& e
|| ou
! negao
Exemplos:
a >= b
(a = = 0) || (b != 0)
! ((a = = 0) && (b<3))
45
Operador & Inflao
o operador de endereamento
(ponteiro):
&a o endereo da varivel a
acesso ao contedo da varivel a.
46
Incremento/decremento
x = x + 1; /* isto incrementa x */
x++; /* isto incrementa x */
++x; /* isto incrementa x */
s+=i; /* s=s+i*/
z = y++; /* z = y e depois y++ */
z = ++y; /* y++ e depois z = y (novo) */
O decremento de igual modo
47
Regra
v = v operador expresso

v operador= expresso
48
Condicional
a = (b >= 3.0 ? 2.0 : 10.5 );

if (b >= 3.0)
a = 2.0;
else
a = 10.5;
c = (a > b ? a : b); /* c=maior(a,b) */
c = (a > b ? b : a); /* c=menor(a,b) */
49
Entradas e Sadas
50
Sadas
Printf("Bom dia");
puts("Bom dia"); /* para imprimir um string */
putch(a) /* para imprimir um char */
printf ("Meu nome : %s\ne tenho %d anos.", nome,
idade)
51
Entradas
gets(s); /* leitura de um string */
char c;
c = getch();
c = getchar(); /* com echo */
scanf ("%d",&nome);
/* para a leitura da var. nome */
52
Constantes utilizados no printf
\n nova linha
\t tabulao (horizontal)
\v tabulao vertical
\b um espao para trs
\r um return
\a um bip
\\ backslash
\% o caracter %
\{} um apostrofo
\? um ponto de interrogao
53
Converso de Tipos
d notao de decimal
o notao octal
x notao hexadecimal
e notao matemtica
u notao sem sinal
c notao de caracter
s notao de string
f notao de flutuante
54
Formatao
Cada um desses caracteres de converso
utilizado depois do %
para indicar o formato da sada (da
converso)
Mas, entre os dois podemos entrar outros
argumentos:
55
Formatao
- justificar a esquerda
+ o sinal sempre aparente
n o comprimento mnimo da sada (seno
brancos)
0n o comprimento mnimo da sada (seno 0s
esquerda)
n.m para separar as partes antes e depois da
virgula total de n dgitos, cujo m so depois
da virgula.
l para indicar um long
56
#include <stdio.h>
int main()
{
int a; long int b; short int c;
unsigned int d; char e; float f;
double g;
a = 1023; b = 2222; c = 123;
d = 1234; e = X;
f = 3.14159;
g = 3.1415926535898;
...
}
Exemplo
57
{ printf("a = %d\n", a); a = 1023
printf("a = %o\n", a); a = 1777
printf("a = %x\n", a); a = 3ff
printf("b = %ld\n",b); b = 2222
printf("c = %d\n", c); c = 123
printf("d = %u\n", d); d = 1234
printf("e = %c\n", e); e = X
printf("f = %f\n", f); f = 3.141590
printf("g = %f\n", g); g = 3.141593
}
Exemplo
58
{
printf("\n");
printf("a = %d\n", a);
printf("a = %7d\n", a);
printf("a = %-7d\n", a);
c = 5;
d = 8;
printf("a = %*d\n", c, a);
printf("a = %*d\n", d, a);
}
Exemplo
59
{
printf("\n");
printf("f = %f\n", f);
printf("f = %12f\n", f);
printf("f = %12.3f\n", f);
printf("f = %12.5f\n", f);
printf("f = %-12.5f\n", f);
}
Exemplo
60
As sadas so:
f = 3.141590
f = 3.141590
f = 3.142
f = 3.14159
f = 3.14159
Exemplo
61
Diretivas de Compilao
62
So instrues para o pre-processador.
Elas no so instrues C, portanto
elas no terminam por uma virgula.
Para diferenci-las das instrues C, elas
so precedidas pelo smbolo especial #
Temos principalmente as seguintes diretivas:
#include
#define
#if, #else, #endif
Diretivas de compilao
63
Incluso de Fontes: #include
#include <nome de arquivo>
Para a incluso de um arquivo.
A busca do arquivo feita em primeiro no diretrio
atual e depois no local das bibliotecas:
Em Unix: /usr/lib/include
Em DOS: APPEND (~ PATH, mas para os
arquivos de dados e no
para os executveis)
Em Windows: isto especificado no
ambiente
64
Incluso de Fontes: #include
#include nome-de-arquivo
Para a incluso de um arquivo usurio.
Neste caso, a busca do arquivo feita
apenas no diretrio atual. Seno, pode se
especificar o caminho completo do arquivo
65
Exemplo de incluso
...
#include "f2.c"
...
f1.c
for (i=0;i<5;i++)
printf("Oi");
f2.c
...
for (i=0;i<5;i++)
printf("Oi");
...
f1.c
66
Arquivos headers (.h)
Arquivos headers standards:
stdlib, stdio.h, conio.h, etc.
Um arquivo header contm um conjunto
de declaraes de variveis e funes.
Observao:
Os headers includos podem
tambm incluir outros arquivos (mas
no pode existir uma referencia mtua)
67
Substituies: #define
#define MAX 60
#define TRUE 1
#define FALSE 0
#define BOOLEAN int
{
BOOLEAN a=FALSE;
if (a = = TRUE) ...; else ...;
}
(uma conveno: usar os masculos)
68
Macro Substituies: #define
#define maior(A,B) ((A)>(B)?(A):(B))
f()
{
...
maior(i+1,j-1);
...
}
A instruo maior(i+1,j-1) ser
compilada como se nos escrevemos:
((i+1)>(j-1)?(i+1):(j-1))
69
Outros Macros
#define quadrado(a) (a)*(a)
#define quadrado(a) a*a
#define adicionar(a,b) ((a)+(b))
#define adicionar(a,b) (a)+(b)
quadrado(3-2); (3-2)*(3-2) = 1
5*adicionar(2+1,4); 5*((2+1)+(4)) = 35
regra geral: colocar todas as variveis entre
parnteses e o resultado tambm
70
Substituies parciais
#define MAX 60
... /*aqui MAX=60*/
#undef MAX
#define MAX 45
... /*aqui MAX=45*/
71
Compilao condicional (1)
Objetivo: a otimizao
#if (condio)
corpo 1
[#else
corpo 2]
#endif
72
Compilao condicional (2)
#ifdef identificador
corpo 1
#endif
#ifndef identificador
corpo 1
#endif
73
O const
Para declarar variveis constantes podemos
usar a palavra chave const
const int N 20
Isto proibe que N seja modificado no programa
(toda tentativa de modificao vai dar erro)
Diferena para o #define:
- Usando o const teremos uma reserva de um espao
na memria. Ele se aplica sobre qualquer tipo de var.
- O #define serve somente para o pre-processador que
faz as substituies necessrias antes da compilao.
74
Estruturas de Controle
75
Blocos de instrues
{
declaraes
instruo_1
..... /*um bloco de instrues
delimitado por duas chaves*/
instruo_2
}
Em um bloco pode-se declarar variveis,
que ficam visveis somente no bloco.
76
Instruo if...else (1)
If (condio)
instruo_1;
[else
instruo_2;]
Exemplos:
if (a>=b) if (a!=0)
max=a; x=-b/a;
else
max=b;
77
Instruo if...else (2)
Qualquer instruo simples C pode ser
substituda por uma instruo composta:
if (d>0)
{
x1=(-b-sqrt(d))/2*a;
x2=(-b+sqrt(d))/2*a;
}
78
Instruo if...else (3)
Observao: o else refere-se ao ltimo if
If (condio_1)
instruo_1;
else if (condio_2)
instruo_2;
else if (condio_3)
instruo_3;
else
instruo_4;
79
Instruo if...else (4)
int a=3, b=2, c=1, d=0;
if (a>b) if (c<d) b=2*a; else a=2*b;
seno, tem que escrever:
if (a>b)
{
if (c<d) b=2*a;
}
else a=2*b;
80
Instruo if...else (5)
Observao: o else refere ao ltimo if
seno tem que usar chaves (bloco)
If (condio_1)
{
instruo_1;
if (condio_2)
instruo_2;
}
else if (condio_3)
instruo_3;
81
Observao
A condio no obrigatoriamente uma
comparao. Pode ser qualquer
expresso retornando um valor que pode
ser comparado a zero.
int b=0;
if (b) /* equiv. a: if(b!=0)*/
{
...
}
82
Instruo switch (1)
escolha mltipla
switch (expresso)
{
case constante_1:
instrues
break;
case constante_2:
instrues
break;
...
default:
instrues
}
83
Instruo switch (2)
Quando as mesmas instrues devem ser
executadas no caso de um conjunto de
valores:
switch (expresso)
{
case val_1:
...
case val_n:
instrues
break;
case val_3:
instrues
break;
default:
instrues
}
84
Instrues de Repetio
85
while
while (condio)
instruo
instruo pode ser simples ou composta.
Exemplo:
c=s;
while (c!=f)
{
c=getch();
}
condio!=0 ?
instrues
sim
no
f
i
m

d
o


w
h
i
l
e
86
do...while (1)
do
instruo(es)
while (condio)
o equivalente de repeat do Pascal.
A instrues do lao de repetio so
executadas pelo menos uma vez.
87
do...while (2)
do
c=getch();
while (c==s)
condio!=0 ?
instruo
sim
no
f
i
m

d
o


d
o
88
for (1)
for (expresso1, condio, expresso2)
instruo(es)
expresso1 avaliada s uma vez
depois a condio
se condio OK, as instrues so executadas
depois a expresso2, antes de voltar a avaliar
novamente a condio
Exemplo: for (i=1; i<=10; i++)
{
printf(Vasco da Gama);
}
89
for (2)
condio!=0 ?
expresso1
sim
no
f
i
m

d
o


f
o
r
instrues
expresso2
inicializao
90
for (3)
A novidade que as expresses podem ser
instrues mltiplas (separadas por virgula)
Exemplo:
for (i=1,j=10; i<=j; i++,j--)
{
instrues;
}
91
break
O break permite parar a instruo
de repetio (for, do ou while)
Se temos vrios nveis, o controle volta
penltima estrutura de repetio.
for (i=0;i<20;i++)
if (vet[i]==10) break;
92
continue
Utilizada dentro de uma instruo for, while ou
do
O continue permite parar a iterao atual e
passar iterao seguinte.
Exemplo:
for (i=1;i<20;i++)
{
if (vet[i]<0) continue;
...
}
93
Instruo: goto
goto <identificador> ;
permite quebrar a seqncia do programa
Exemplo:
mais:
...
If condio goto mais;
94
Funes
95
Definio de uma funo
Alm das funes predefinidas nos arquivos
header da biblioteca (no diretrio LIB, usando
o #include)
O usurio pode definir novas funes.
Exemplos de funes predefinidas da biblioteca:
stdio.h, math.h, conio.h,
stdlib.h e dos.h
96
Ex. de funes: (stdio.h)
Principalmente:
puts
gets
printf
scanf
97
Ex. de funes: (math.h)
abs mdulo de int. int abs(int)
fabs mdulo de real double fabs(double)
exp exponencial double exp(double)
ceil arredondar ao max double ceil(double)
floor arredondar ao min double floor(double)
pow x
y
double pow(double x,double y)
pow10 10
x
double pow10(double)
hypot hipotenusa double hypot(double, double)
sqrt raiz quadrada double sqrt(double)
98
Ex. de funes: (conio.h)
clrscr apaga a tela void clrscr ()
clreol apaga o resto da linha void clreol ()
delline apaga a linha atual void delline ()
insline insere uma linha void insline ()
gotoxy posiciona o cursor void gotoxy (int x, int y)
kbhit testa se tecla int kbhit ()
putch imprima um char c int putch (int c)
getch leia char sem echo int putch ()
herex posio x do cursor int wherex ()
herey posio y do cursor int wherey ()
99
Ex. de funes: (stdlib.h)
min retorna o min type min(type, type)
max retorna o max type max(type, type)
rand ret. num. alea. int rand()
exit ret. nvel de erro void exit(int)
random ret. num. alea de 0 a n-1 int random(int n)
randomize inicializa o gen. al. int randomize()
precisa tambm de <time.h>
100
Ex. de funes: dos.h
delay
sound
nosound parar o som
sleep suspende em seg void sleep(unsigned s)
exemplo:
{ sound(300); /* emitir um som de 300 Hz*/
delay(2000); /* esperar 2 segundos */
nosound(); /* antes de parar */
}
101
Exemplos de funes
graphics.h
rectangle desenha um retngulo
void rectangle (int e, int c, int d, int b)
string.h
102
Definio de uma funo
tipo identificador ([lista de id.])
[lista de declaraes 1]
{
[lista de declaraes 2]
lista de instrues
}
103
Semntica
tipo: o tipo do valor devolvido pela funo
identificador: nome da funo
lista dos identificadores: os parmetros
formais
lista de declaraes 1: a lista de declarao
dos parmetros formais
lista de declaraes 2: declarao das
variveis locais a funo
lista de instrues: so as instrues a executar
quando a funo chamada.
104
Exemplo
float media (a,b)
float a,b; /* declarao dos
parmetros formais */
{
float resultado; /* var. locais */
resultado=(a+b)/2;
return (resultado); /* retornar o
res. ao remetente */
}
105
Os parmetros formais - opcionais
double pi () /* no temos param.
formais */
{ /* no temos var. locais */
return (3.14159);
}
106
Observao
A prototipagem da funo pode ser feita de uma
vez:
int min (int a, int b)
{
if (a<b)
return (a);
else
return (b);
}
107
Chamada de uma funo
identificador (lista de expresses)
As expresses so avaliadas, depois passadas
como parmetros efetivos funo de nome
identificador.
{
int m_1, m_2; float p, d=4.5;
m_1 = max (4,3); m_2 = max(6*2-3,10);
p = d * pi();
}
108
Procedimentos
Funes que no retornam valores: usando o
tipo especial void
void linha ()
{
printf("-------------------------\n");
}
Observao: no temos aqui a instruo return
(o tipo especial void no existia nas
primeiras verses da linguagem)
109
Omisso do tipo da funo!
C considera por defaut o tipo int.
somar (int a, int b)
{
return (a+b);
}
Melhor no usar esta possibilidade.
110
Passagem dos Parmetros
int somar (int x, int y)
{
return (x+y);
}
void main ()
{
int a=8, b=5, s;
s = somar(a,b); /*os parmetros efetivos*/
}
111
Passagem por Valor
Na chamada temos passagem de parmetros.
Mas, as modificaes dos parmetros formais
no afetam os parmetros efetivos.
112
Passagem por Referncia
(ou por endereo)
Usar o operador de endereamento &
void somar (int x, int y, int * som)
{
*som = x+y;
}
void main ()
{
int a=5, b=6, s;
somar(a,b, &s);
printf("%d + %d = %d",a,b,s);
}
113
Outro uso do void
void f (void)
{
...
}
para indicar que a funo no tem
parmetros
114
Declarao de Funes
Uma funo F conhecida implicitamente
por uma outra funo G se elas so
definidas no mesmo arquivo, e que F
definida antes de G.
Fora desse caso, e para um controle de tipo
e um bom link, preciso declarar as
funes antes de usar.
115
Exemplo
void main (void)
{
int maior (int, int);
maior (2,8);
}
...
int maior (int x, int y)
{
return (x>y?x:y);
}
/*a main pode ser definida antes*/
116
Dois formatos para a declarao
int maior (); 1
a
int maior (int x, int y); 2
a
Mas, melhor usar o segundo formato
que mais completo
117
Funes Iterativas
exemplo do fatorial
long int fat (long int n)
{
long int i,res=1;
for (i=1;i<=n;i++)
res=res*i;
return (res);
}
118
Funes Recursivas
exemplo do fatorial
long int fat (long int n)
{
if (n == 1)
return 1;
else
return (n*fat(n-1));
}
119
Exerccios
Escreva as funes real_dlar e
dlar_real de converses Real-Dlar e vice
versa.
Escreva as verses recursiva e iterativa
da funo soma que retorna a soma dos
n primeiros termos:
S(n) = 1 + 1/2 + 1/3 + ... + 1/(n-1) + 1/n
Escreve a funo S(n) tal que:
S(n) = 1/n - 2/(n-1) +3/(n-2) + ... - (n-1)/2 + n/1
120
Declaraes
121
Escopo das declaraes
so 4 escopos:
Um identificador declarado fora das funes, tem
um escopo em todo o programa.
Um parmetro formal de uma funo, tem
um escopo local funo.
Um identificador declarado em um bloco
tem um escopo local ao bloco.
Uma etiqueta de instruo, tem escopo em
toda a funo onde ela declarada.
122
Visibilidade dos identificadores
int i=1;
int j=1;
void p()
{
int i=2; /* este i cobre o precedente */
int k;
if (a==b)
{
int i=3; /*cobre o i precedente*/
int j=2; /* cobre o j precedente*/
int k; /*cobre o k precedente*/
}
}
123
Variveis Estticas:
Alocao no incio do programa e liberao
no final da execuo do programa.
Variveis Automticas
Alocao na entrada de uma instruo
composta (um bloco) e liberao na sada.
Variveis Dinmicas
A declarao e liberao so explicitamente
realizadas pelo programador (usando malloc
e free). Mas, essas funes so da biblioteca
e no fazem parte integrante da linguagem.
Durao vida de uma varivel
124
Durao vida de uma varivel
A durao de vida de uma varivel depende
normalmente de seu escopo de declarao:
varivel global var. esttica
varivel local var. automtica
125
As variveis globais so variveis estticas.
As variveis locais podem ser estticas ou
automticas (dependendo do programador),
usando os qualificadores de classes de
armazenagem: static e auto.
Por default, uma varivel local automtica.
Durao vida de uma varivel
126
Indicadores de classes de memria
Em C, temos quatro indicadores de classes
de memria:
auto
static
register
extern
127
auto
{auto int i; ... }
Este tipo de indicador autorizado somente para
as variveis locais a uma instruo composta
(um bloco).
Ele indica que a varivel tem uma durao
de vida local ao bloco.
O uso deste indicador quase inexistente, pois
por default toda varivel local automtica
128
static
{static int i; ... }
O static indica que a varivel tem uma
durao de vida ao longo da execuo do
programa. Mas que ela fica local ao bloco
(ela fica desconhecida fora de seu bloco).
Portanto, a varivel guardar seu valor para
cada chamada ao bloco.
Este indicador pode ser usado para as
declaraes de variveis e funes.
129
exemplo de uso de static
void f ()
{
static int num_chamadas = 0;
num_chamadas++; /* para contar
quantas vezes f foi chamada */
}
A varivel num_chamada inicializada
somente uma vez. Tem durao de vida ao
longo da execuo do programa. Mas ela tem
escopo local.
130
register
{register int a,b; ... }
Este tipo de indicador autorizado somente para as
variveis locais a uma instruo composta (um
bloco) e para as declaraes de parmetros de
funes.
Ele tem o significado do auto, alm de provocar o
armazenamento da varivel
em um registro e no na memria.
acesso mais rpido.
Claro que isto depende das capacidades da
mquina (nmero e tamanho dos registros)
131
extern
int a;
void f() {... extern int a; ...}
Os outros indicadores so relacionados s
variveis locais.
Uma varivel global definida fora de
qualquer corpo de funo.
O extern permite usar (acessar) uma varivel
que definida fora.
Este indicador autorizado para as
declaraes de variveis e funes.
132
Classes de memria (1)
Na execuo de um programa, existe trs
zonas de memria:
Zona das variveis estticas ;
Zona das variveis automticas
(organizada em forma de pilhas, pois as funes podem ser
recursivas)
Zona das variveis dinmicas (organizada em forma de
monto ou tas / stack)
133
Classes de memria (2)
Esta diviso existe nas outras linguagens,
mas a alocao feita pelo compilador.
Ao contrrio, em C a declarao da classe
da varivel feita pelo prprio
programador.
auto, static e register so
indicadores de classe de memria (mas
o extern no realmente)
134
Tabelas
135
Tabelas
O objetivo da estrutura de tabela
agrupar um conjunto de informaes de
mesmo tipo em um mesmo nome.
Uma tabela pode ser multidimensional ou
unidimensional (vetor).
136
Declarao
float vet[10];
long int v1[8], v2[15];
/* v1 um vetor de 8 long int
e v2 um vetor de 15 long int */
Os elementos so indexados de 0 a
N-1
137
Dimenso
Na prtica, recomendado definir sempre
uma constante que indica o nmero de
elementos:
#define N 60
short int v[N];
/* declara um vetor de 60
inteiros indexado de 0 a 59 */
138
Acesso aos elementos
Sintaxe:
nome-varivel [expresso]
expresso deve retornar um inteiro (o indexador)
Exemplos:
vet[0]=6;
vet[4+1]=-2;
x=3*vet[2*a-b];
139
Inicializao
#define N 4
int v[N]={1,2,3,4};
Incializao de somente uma parte do vetor:
#define N 10
int v[N]={1,2}; //o resto ser zerado
Inicializao pelo mesmo valor:
for (i=0;i<=9;i++) v[i]=2;
Inicializao pelo usurio:
for (i=0;i<=9;i++)
scanf("%d",&v[i]);
140
Operadores abrangentes
lembramos que:
x++ incrementa x mas retorna o valor inicial
++x incrementa x e retorna o valor incrementado
i=0;
v[i++]=0; /* v[0]=0 e i=i+1 */
v[i++]=0; /* v[1]=0 e i=i+1 */
i=1;
v[++i]=0; /* i=i+1 e v[2]=0 */
v[++i]=0; /* i=i+1 e v[3]=0 */
idem para o operador --
141
Uso da instruo nula
Inicializao de um vetor:
for (i=0;i<10;v[i++]=1);
Isto equivalente a:
for (i=0;i<10;i++) v[i]=1;
Pesquisar em um vetor:
for (i=0; i<N && t[i]!=10; i++);
/* usando a instruo nula */
Isto equivalente a:
for (i=0; i<N; i++)
if t[i]==10 break;
142
Tabelas MultiDimensionais
Matrizes
Declarao:
int mat [3][4]; /* matriz bidimensional
de 3 linhas 4 colunas */
Inicialiazao:
int mat [3][4] =
{
{5,6,8,1},
{4,3,0,9},
{12,7,4,8},
}
143
Exemplo
/* Declarao: */
#define L 4;
#define C 3;
int mat[L][C];
/* leitura: */
for (i=0;i<=L;i++)
for (j=0;j<=C;j++)
{
printf("digite o elemento [%d,%d]: ",i,j);
scanf("%d",&mat[i][j]);
}
144
Observao 1
for (i=0,j=0;i<L && j<C;i++,j++)
{
printf("digite o elemento [%d,%d]: ",i,j);
scanf("%d",&mat[i][j]);
}
no a mesma coisa que:
for (i=0;i<=L;i++)
for (j=0;i<=C;j++)
{
printf("digite o elemento [%d,%d]: ",i,j);
scanf("%d",&mat[i][j]);
}
145
Observao 2
int sum (int n)
{
int res=0;
for (;n>0;n--) /*n inicializada na chamada*/
res=res+n;
return (res);
}
chamada: sum(5)
O que faz este cdigo?
146
Exerccios
A.1 Escreva o procedimento ini_num_dias que
inicializa um vetor num_dias[12] que indica para cada
ms do ano seu nmero de dias: (num_dias[i] indica o
nmero de dias do ms i do ano), sabendo que:
Se i=2 ento num_dias=28;
Se (i par e i<=7) ou (se i impar e i>7) ento
num_dias=30 Seno num_dias=31.
A.2 Escreva o procedimento imp_num_dias que
imprima os nmeros de dias de todos os meses do
ano.
B. Escreva a funo ordenar que ordena um vetor.
C. Escreva a funo palindromo que determina se um
vetor um palindromo.
147
Tipos Enumerados
148
enum
A enumerao permite de agrupar um conjunto
de constantes (compartilhando a mesma
semntica)
exemplos:
enum dias {Domingo, Segunda, Tera,
Quarta, Quinta, Sexta, Sbado};
declarao:
dias d1,d2=Quinta;
enum defini um novo tipo cujo os elementos
so numerados automaticamente de pelo
compilador: 0 1 2 ...
149
Exemplo
#include <stdio.h>
enum dias {Segunda,Tera,Quarta,Quinta,
Sexta,Sbado,Domingo} d;
// d uma varivel declarada de tipo dias
void main (void)
{ // dias d; uma outra maneira de declarar
for(d = Segunda ; d < Domingo ; d++)
printf(O cdigo do dia : %d\n", d);
}
Vai imprimir os valores dos dias: 0, 1 at 6.
150
enum
Essa numerao permite comparar os elementos
do tipo: if (d1<=d2) ...
Portanto podemos mudar essa numerao:
enum boolean {true=1,false=0};
Quando um item no numerado ele pega
o valor de seu precedente:
enum temperatura
{baixa=2,media=4,alta};
151
Ponteiros
152
Variveis Dinmicas
Todas as variveis vistas at agora so
estticas (reserva imediata na memria),
contudo precisamos de variveis dinmicas
Um ponteiro uma referncia sobre
um objeto na memria ( um endereo).
153
Exemplo de Declarao de Ponteiros:
float * pf
/* declara que pf um ponteiro sobre um real */
pf
4.6
Variveis Dinmicas
154
Os Operadores & e * (1)
O operador de endereamento &
se aplica sobre uma varivel e permite
retornar seu endereo memria
O operador de indireo *
se aplica sobre um ponteiro e permite
retornar (manipular) o objeto
apontado.
155
Os Operadores & e * (2)
V
(Varivel)
P
(Ponteiro)
&v
*P
156
Exemplo
pi
j
i
6
i=5;
pi=&i;
*pi=6;
j=*pi-2;
pi=&j;
int i,j;
int *pi;
/* pi um ponteiro sobre um inteiro */
5
&i
4
&j
157
Exerccio
1. Declare um inteiro i e um ponteiro p
sobre um inteiro
2. Inicialize o inteiro com um valor qualquer
3. Aponte o ponteiro sobre a varivel i
4. Imprima o valor de i
5. Modifique o valor de i usando o ponteiro
6. Imprima o novo valor de i
158
int i; /* 1 */
int * p; /* 1 */
i=8; /* 2 */
p=&i; /* 3 */
printf("i= %d\n",i); /* 4 */
*p=5; /* 5 */
printf("novo i= %d\n",i); /* 6 */
159
Passagem de Parmetros
Passagem de parmetros (dois tipos):
por valor
por referncia (passar o endereo da varivel)
Estratgias adotadas pelas linguagens:
Todo feito por referncia (FORTRAN, PL/1)
Temos a escolha entre a passagem por valor
ou por referncia (caso de PASCAL)
Toda passagem feita por valor (caso de C)
160
Estratgia de C
Em C, toda passagem de parmetros
portanto feita por valor.
Como ento fazer as passagens por
referncia? A soluo de declarar os
parmetros formais de tipo ponteiro.
Isto feito pelo uso do operador &
(usado na chamada a funo).
161
Exemplo
void adicionar (int a, int b, int * res)
{
*res=a+b;
}
void main (void)
{
int i,j,k;
adicionar (i,j,&k);
}
observe a declarao de res
como um ponteiro sobre um
inteiro: um endereo
observe que na chamada tem
que passar o endereo da
varivel onde deseja-se
recuperar o resultado
162
Um outro exemplo
A funo troca
void troca (int * x, int * y)
{
int temp;
temp=*x;
*x=*y;
*y=temp;
}
chamada da funo
troca(&a,&b); /* passagem por referncia */
163
Funes Genricas
O problema que esta funo troca que ns definimos
se aplica somente sobre os inteiros
void troca (void * x, void * y)
{
int temp;
temp=*x;
*x=*y;
*y=temp;
}
Infelizmente isto no pode ser feito em C
Mas o problema resolvido em C++
164
Tabelas e Ponteiros
165
Relao entre Tabela e Ponteiros
O nome de uma tabela no um identificador de
dados mas um ponteiro:
#define N 45
int t[N];
t o endereo do primeiro elemento: t[0]
t=&t[0]
t[i] = *(t + i)
t + i: Incrementa de i vezes o tamanho
dos objetos do vetor (e no de i unidades)
166
Conseqncia 1
Trs conseqncias principais da
considerao que uma tabela um
ponteiro:
O operador de indexao [ ] no til:
Mas ele foi adotado pela linguagem parar
no quebrar os costumes dos
programadores
167
Conseqncia 2
Manipulao de sub-tabelas:
int t[10];
int * p;
p=&t[2];
podemos escrever ento p[0], p[1]...
(p[0]=t[2],...)
t
0 1 2 3 9
p
168
Conseqncia 3
O operador de indexao comutativo:
t[i] = i[t]
isto porque a adio comutativa:
t[i] *(t+i)
i[t] *(i+t)
Mas, por razes de legibilidade do
programa esta possibilidade muito
pouco utilizada.
169
Aritmtica dos Ponteiros
Podem ser efetuadas operaes de adio
e de subtrao sobre os ponteiros ou entre
ponteiros e inteiros.
Esta possibilidade usada para
manipulao de tabelas
170
Ilustrao do Clculo de Ponteiros
#define N 10
int t[N];
int *p, *q, *r, *s;
p=&t[0]; /*aponta sobre o 1
o
elem do vetor*/
q=p+(N-1); /*aponta sobre o ltimo elem do vetor*/
r=&t[N-1]; /*aponta sobre o ltimo elem do vetor*/
s=r-(N-1); /*aponta sobre o 1
o
elem do vetor*/
171
Passagem de Parmetros
Em C uma tabela pode ser passada como
parmetro a uma funo
Quando isto feito, em realidade, o endereo
do primeiro elemento que passado como
parmetro.
A passagem ento feita por referncia.
O parmetro formal da funo chamada
deve ento ser declarado de tipo ponteiro
172
1
a
Abordagem
void imp_tabela (int * t, int num_elem)
{
int i;
for (i=0;i<num_elem;i++)
printf("%d",*(t+i));
}
chamada: imp_tabela(tab,N); /* que equiv. a: */
imp_tabela(&tab[0],N);
173
Crtica
Este mtodo apresenta inconvenientes:
A declarao e a chamada no parecem
muitos naturais para os programadores
Na declarao int * t no mostra se t
aponta sobre um inteiro ou sobre uma zona de
inteiros (a tabela)
174
2
a
Abordagem
Por esta razo, C permite uma declarao mais
natural dos parmetros formais:
void imp_tabela (int t[],int n)
{
int i;
for (i=0;i<n;i++)
printf("%d",t[i]);
}
Ateno: No preciso conhecer o tamanho exato da
tabela. o tamanho geralmente passado como
parmetro separado.
chamada: imp_tabela(tab,L);
175
Tabelas Multi Dimensionais
No caso de uma tabela multidimensional
somente a primeira dimenso pode no
estar especificada:
int min (int m[][C], int l)
{ int i,j,min=m[0][0];
for(i=0,j=0;i<l&&j<C;i++,j++)
if (m[i][j]<min) min=m[i][j];
return(min);
}
chamada: min(mat,L);
176
Algumas consideraes
A funo min aplicada a uma tabela que tem
qualquer nmero de linhas, mas deve ter um exato C de
colunas.
As outras dimenses ( 1
a
), devem ser especificadas por
que o compilador precisa para gerar o cdigo que
permite o acesso aos elementos:
No caso de uma matriz binria t por exemplo, o endereo
de t[i][j] : t+(i*C+j)*T (T o tamanho de um
elemento de t, C o nmero de colunas)
Representao da tabela na memria:
11 12 13 14 21 22 23 24 31 32 33 34 41...
177
Modificao dos elementos
void f (int t[],int nb_elem)
{
int i;
for (i=0;i<nb_elem;i++)
t[i]++;
}
a chamada: f(tab,L);
/* j que a passagem de parmetros feita por referncia
ento qualquer modificaes sobre o vetor fsica */
O que faz esta funo?
178
Tabelas de ponteiros
possvel declarar uma tabela de ponteiros:
exemplo:
#define N 15
char * tab[N]; /* declara um vetor de ponteiros
sobre elementos de tipo caracter */
acesso:
*tab[i]
Objeto
apontado
tab
*tab[i]
i
179
Ponteiro de Ponteiro
180
Ortogonalidade do operador *
J que um ponteiro uma varivel como as
outras, muito normal que um ponteiro aponte
sobre um ponteiro
Um exemplo um ponteiro sobre um ponteiro
sobre mais um inteiro
declarao:
int **ppint
ppint
int
181
Argumentos do main
Um programa C pode ser chamado
externamente com alguns parmetros:
A funo main recebe sempre dois
parmetros:
argc (argument count) que determine o nmero
de argumentos da linha de comando; e
argv (argument vector), que um ponteiro sobre
uma tabela de ponteiros sobre strings:
182
argv
um ponteiro sobre um vetor de ponteiros
sobre strings:
char * argv[];
argv[0] aponta sobre o nome do arquivo
(nome do programa)
argv[i] vai apontar sobre os argumentos
passados ao programa na linha de comandos.
183
exemplo
Suponha: programa achar_max pega como
parmetros um conjunto qualquer de strings e que
deve determinar e imprimir a maior string:
argv[0] o nome do programa: achar_max,e os
outros argv[i] so os argumentos passados ao
programa na linha de comandos.
argv
achar_max\0
\0
\0
\0
184
#include <stdio.h>
#include <string.h>
void main (int argc, char * argv[])
{
int com_max=0, arg_max=0; argc--;
while (argc>=1)
{
if (strlen(argv[argc])>com_max)
{
com_max=strlen(argv[argc]);
arg_max=argc;
}
argc--;
}
if (arg_max) printf("O string maior : %s", argv[arg_max]);
}
185
Strings
186
String ~ Vetor
Um string um conjunto de caracteres.
Em C, um string uma estrutura
equivalente estrutura de vetor,
A nica diferena que o string termina
sempre pelo caractere \0
Isto para facilitar o tratamento dos strings
(para poder detectar o fim do string)
187
Declarao
O tipo string no existe em C,
Portanto existe duas maneiras para
simular este tipo de variveis:
Como um vetor de char, ou
Como um ponteiro sobre uma zona
de chars
188
Como Vetor de Caracteres
Declarao:
#define N 20
char ch [N];
Os strings declarados como vetor de chars
tm um tamanho limite fixo (o tamanho do
vetor).
Se o tamanho do string menor do que o
tamanho do vetor, o compilador C completa
pelo caractere especial \0 para indicar o fim
do string.
189
Inicializao de Vetor de Caracteres
A inicializao de um vetor de char pode ser feita,
no momento da declarao, de duas maneiras:
1. Atribuindo um conjunto de caracteres:
char ch [20]={e,x,e,m,p,l,o};
(como normalmente feito para inicializar qualquer tipo
de vetor).
2. Atribuindo um string ( mais prtica):
char ch[20]= "exemplo";
O tamanho pode ou no estar especificado:
char nome[]="este tem 23 caracteres";
190
Acesso aos Elementos
feito de uma maneira normal, como para
qualquer tipo de vetor:
#define N 3
char ch [N]={O,i};
ch[0]= H /* refere ao 1
o
caractere */
ch[1] /* refere ao 2
o
caractere */
...
ch[N-1] /* refere ao N
simo
caractere */
O i \0
H i \0
191
Como Ponteiro sobre Caracteres
A manipulao dos strings como vetores de
caracteres pode aparecer como pouco prtica.
Portanto, podemos criar strings de tamanho
dinmico usando um ponteiro sobre um char:
char * ch = "exemplo";
Contrariamente outra maneira, a reserva do
espao memria no feita no momento da
declarao, mas dinamicamente no momento da
atribuio.
192
Inicializao e Atribuio
A Inicializao feita diretamente por uma string:
char * ch = "exemplo";
C completa o string pelo caracter \0 indicando
o fim do string.
A Atribuio tambm direta (contrariamente ao vetor de char):
ch = "uma mudana";
ch = "outra mudana";
Isto no uma copia mas uma atribuio de ponteiros.
uma mudana\0
outra mudana\0
ch
193
Manipulao de Strings
As funes de manipulao de strings so
definidas no arquivo da biblioteca string.h
Temos principalmente as seguintes
funes:
strcpy, strncpy
strlen
strcat, strncat
strcmp, strncmp
strchr, strrchr
194
Strcpy/strncpy
A funo especial strcpy permite atribuir um
valor texto a uma varivel de tipo texto:
O strcpy apresenta dois formatos de uso:
strcpy(string1,string2);
strncpy(string1,string2,N);
exemplo:
char *ch1="boa", *ch2="noite";
strcpy(ch1,"isto um exemplo");
strncpy(ch2,ch1,4); /* ch2 vai pegar "isto" */
195
strlen
strlen permite retornar o tamanho de um
string: nmero de chars que compem o
string (o \0 no faz parte)
exemplo:
int a;
char * nome;
strcpy(nome,brasil");
a=strlen(nome); /* a=6 */
196
strcat/strncat
strcat se aplica sobre dois strings e retorna um
ponteiro sobre a concatenao dos dois.
exemplo:
char *ch1="boa", *ch2="noite",
*ch3, *ch4;
ch3=strcat(ch1,ch2);
ch4=strncat(ch1,ch2,3);
printf("%s %s",ch3,ch4);
/* vai imprimir boanoite boanoi*/
197
strcmp/strncmp
Lembramos que as letras so ordenadas dando
seu cdigo: a< ... z< A...<Z
strcmp compara dois strings s1 e s2 e
retorna um valor: negativo se s1 < s2
0 se s1 == s2
positivo se s1 > s2
exemplo:
char *ch1="boa tarde",
*ch2="boa noite";
int a,b;
a=strcmp(ch1,ch2);
b=strncmp(ch1,ch2,4);
/* a vai receber um valor >0 e b 0*/
198
strchr/strrchr
strchr procura por um caractere em um string e
retorna um ponteiro sobre sua ltima ocorrncia, seno
retorna null.
exemplo:
char ch[]="informtica";
char *pc, c='f';
pc=strchr(ch,c);
if (pc) /* i.e. if pc!=null */
printf("%d",*pc);
else
printf("Caractere inexistente");
O strrchr faz a busca no senso inverso.
199
touppar/tolower
toupper converte um caractere minsculo em
maisculo.
tolower faz o contrrio.
# include <ctype.h>
char c='a';
c=toupper(c); /* c= 'A' */
c=toupper(c); /* c j esta ='A' */
c=tolower(c); /* c volta a ser 'a' */
200
Exerccios 1
A. Defina a funo ocorrncia que retorna o
nmero de ocorrncias de um caractere em um string.
B.1 Defina a funo tamanho1 que pega como
parmetro um vetor de caracteres e retorna seu
comprimento.
B.2 Defina tamanho2 que implementa a mesma funo
mas que pega como parmetro um ponteiro sobre uma zona
de caracteres.
B.3 Defina o main que chama essas duas funes.
201
int tamanho1 (char s[]) /* com um vetor */
{
int i=0;
while (s[i]) /* equiv. while (s[i]!= '\0' ) */
i++;
return (i);
}
int tamanho2 (char * s) /*com os ponteiros*/
{
int i=0;
while (*s) /* equiv. while (*s!= '\0 ') */
{i++;s++;}
return (i);
}
202
void main (void)
{
char ch[]="So Luis";
int a,b;
a=tamanho1(ch); /* a= 8*/
b=tamanho2(ch); /* b= 8*/
printf("O tamanho de %s : %d\n",ch,a);
printf("O tamanho de %s : %d\n",ch,b);
}
203
Exerccios 2: Criptografia Simples
1. Defina as funes Criptar e Decriptar que
codificam e decodificam um caractere aplicando o
seguinte algoritmo de criptografia:
- Um caractere substitudo por um outro
aplicando um shift de 3 (por exemplo a seria
substitudo por D).
- Apenas os caracteres do alfabeto so codificados.
- Os masculos passam a ser minsculos e
vice-versa.
2. Defina a funo main que leia e codifica ou
decodifica uma mensagem usando as funes definidas
acima.
204
Tipos usurios
205
typedef
Podemos definir novos tipos usando o
typedef:
typedef <tipo> <sinnimo>
exemplo:
typedef float largura;
typedef float comprimento;
largura l;
comprimento c=2.5;
l=c; //* warning *//
206
typedef e struct
O typedef se usa mais com o tipo struct
(as estruturas)
207
Estruturas
208
Declarao: mtodo 1
struct cliente {
int cpf;
char nome [20];
char endereco[60];
};
struct cliente c1,c2,c3;
209
Declarao: mtodo 2
Podemos criar estruturas sem nome:
struct {
int cpf;
char nome [20];
char endereco[60];
} c1,c2;
Problema:
para criar uma outra varivel de mesmo
tipo em outro lugar do programa preciso
rescrever tudo.
210
Declarao: mtodo 3
Podemos, no mesmo tempo, dar um nome
estrutura e declarar as variveis:
struct cliente {
int cpf;
char nome [20];
char endereco[60];
} c1,c2;
struct cliente c3;
211
Declarao: mtodo 4
Definindo um tipo estrutura
typedef struct {
int cpf;
char nome [20];
char endereco[60];
} Cliente;
Cliente c1,c2={28400,"Maria","Rua
Liberdade, N. 140"};
212
Acesso aos Campos
Usando o operador de seleo: . (o ponto)
nome-estrutura.nome-do-campo
exemplo:
c2.nome retorna o campo nome da
estrutura c1: Maria
c2.nome=" Jeane" Muda o contedo de
nome
213
Exemplo
void imprimir_cliente (Cliente c)
{
printf("cpf: %d\n%s\n%s",
c.cpf,c.nome,c.endereco);
}
chamada da funo:
imprimir_cliente (c2);
214
Combinao de Estruturas
Podemos definir estruturas de
estruturas, estruturas de vetores,
vetores de estruturas....
exemplo
typedef struct {int num; char * rua;
char * bairro; int cep} End;
typedef struct {int cpf; char * nome;
End endereco} Pessoa;
215
Vetores de Estruturas
Podemos criar um vetor de estruturas (dois
mtodos):
exemplo:
struct cliente vet[100]; /* seguindo o mt. 1*/
Cliente vet[100]; /*seguindo o mt. 4*/
declara um vetor de 100 clientes.
Referencia aos elementos:
Para referenciar o nome do isimo cliente do
vetor: vet[i].nome
216
Exerccio
Escreve um programa C que:
Declara um vetor de alunos: turma (um aluno
definido pelo cpd, nome, trs notas, mdia, e conceito)
Preenche esse vetor (campos: cpd, nome, e notas).
Preenche os campos mdia e conceito (bom se
mdia 8, regular se 7 e ruim seno);
Define a funo que imprime todos o elementos
do vetor.
Define a funo que pesquisa um elemento do vetor
(pesquisa pelo nome, pelo cpd, ou pelo conceito).
217
Estruturas e Ponteiros
218
Estruturas dinmicas
Usando as estruturas e os ponteiros
podemos entrar no mundo das estruturas
auto referenciais:
Listas, Arvores, Grafos, etc.
219
Ponteiros sobre uma Estrutura
typedef struct {
char * nome;
int idade;
} Pessoa ;
Pessoa pess;
/* pess uma varivel de tipo pessoa */
Pessoa *pp;
/* p um ponteiro sobre uma pessoa */
pp=&pess;
/* p agora aponta sobre a pessoa pess */
220
Ponteiros sobre uma Estrutura
pess.idade=18;
pess.nome="joao";
Para acessar aos campos da estrutura apontada
por pp usamos o operador ->
pp->nome; /* equiv. a pess.nome */
pp->idade=25; /* pess.idade=18 */
printf("%s",pp->nome);
// escreveria Joo
printf("%d",pp->idade);
// escreveria 25
221
Para acessar o campo nome de pessoa
apontada por um ponteiro pp:
*pp.nome
Mas o operador de seleo . mais prioritrio
do que o operador de indireo * isto
equiv. a: *(pp.nome)
o que est errado (pois pp no uma
estrutura).
Deveremos escrever:
(*pp).nome
Mas esta notao um pouco complicada.
Por isso temos um novo operador -> (pp->nome)
Observao sobre o acesso
222
Estrutura apontando sobre uma
outra Estrutura (1)
exemplo:
struct pessoa {
...
struct pessoa *
next;
} ;
/* next um ponteiro sobre
uma outra pessoa */
223
exemplo:
typedef struct pessoa * PtrPessoa;
// PtrPessoa um ponteiro sobre a estrutura pessoa
typedef struct pessoa {
char nome[30];
int idade;
PtrPessoa next;
} Pessoa;
/* next um ponteiro sobre uma outra pessoa */
PtrPessoa pp;
Estrutura apontando sobre uma
outra Estrutura (1)
224
Ilustrao
CPF
nome
endereco
next
CPF
nome
endereco
next
225
Acessos aos elementos de uma
Estrutura Apontada
PtrPessoa p;
...
printf("Entra com o nome: ");
scanf("%s",&p->nome);
printf("Entra com a idade: ");
scanf("%d",&p->idade);
p->next=NULL;
226
Tamanho alocado uma Estrutura
O tamanho alocado a um tipo pode ser
conhecido usando o operador sizeof (a
medida feita em nmero de bytes).
sizeof pode ser usada de duas maneiras
(aplicao a um tipo ou uma varivel)
exemplos:
int tamanho,i;
tamanho=sizeof i;
tamanho=sizeof (short i);
tamanho=sizeof (Pessoa);
227
Listas
O fato de que uma estrutura pode apontar para
uma outra permite criar listas encadeadas.
Uma lista encadeada til principalmente
quando ns no sabemos a priori (no momento da
compilao) o nmero de seus elementos, o que
uma necessidade no caso do uso do tipo vetor.
Contrariamente aos vetores, uma lista
encadeada uma estrutura dinmica: os
elementos so criados dinamicamente:
228
Alocao e Liberao de Memria
Para poder criar listas preciso poder
alocar memria dinamicamente:
A alocao e liberao de memria feita
usando as funes malloc e calloc:
malloc para a alocao do espao memria
para um elemento; e
calloc para a alocao do espao memria
para um conjunto de elementos.
229
malloc
malloc pega um nico parmetro que
o tamanho (em bytes) do espao memria
do elemento que ns desejamos criar, e
retorna um ponteiro sobre o elemento criado.
Obs. O tamanho do elemento obtido usando
o operador sizeof.
exemplo:
Pessoa * p;
p=malloc(sizeof(Pessoa));
p=malloc(sizeof(char));
230
calloc
calloc pega dois parmetros:
- o nmero de elementos que
desejamos criar;
- e o tamanho de um elemento (em
bytes).
O objetivo de alocar espaos para
vrios
elementos de s uma vez.
231
calloc
exemplo:
Pessoa * p;
int num_elementos=4;
...
p=calloc(num_elemenetos,
sizeof(Pessoa));
Podemos, depois, usar p[0],
p[1], ...
P[num_elementos - 1]
232
Observao
As funes malloc e calloc so definidas
no arquivo <alloc.h> da biblioteca.
Geralmente antes do malloc tem que
especificar o tipo da estrutura cujo o
ponteiro que ser criado vai apontar:
pat=(PtrPessoa)malloc(sizeof(Pessoa));
p=(char *)malloc(sizeof(char));
233
null
Quando no tem mais espao livre, as
funes malloc e calloc retornam
o valor null
Este valor pode servir tambm para
inicializar uma ponteiro exprimindo
que ele aponta sobre nada.
234
Liberao de Memria
Podemos liberar o espao memria alocado para
uma varivel dinmica:
free(nome-do-ponteiro);
int * p;
...
p=(int *)malloc(sizeof(int));
// 2 bytes
...
free(p); /* liberao de p */
235
As Estruturas como Parmetros
C no permite passar uma estrutura como
parmetro uma funo.
Mas nada proibe passar um ponteiro
sobre uma estrutura:
236
Exemplo
typedef struct {int dia,mes,ano;} data;
/* funo de comparao entre duas datas */
int comp_datas(data * d1, data * d2)
{
if (d1->ano==d2->ano) && ...
return 1;
else return 0;
}
data d1,d2; ...
comp_datas (&d1,&d2);
237
Funes retornando Estruturas
Uma funo no pode retornar uma estrutura
mas pode retornar um ponteiro sobre uma
estrutura:
/ * funo retornando um ponteiro sobre uma data 01/01/2000 */
data * d2001 ()
{ data * p; p=malloc(sizeof(data));
p->dia=1; p->mes=1; p->ano=2000;
return (p);
}
data * d; d=d2001();
238
Observao
Pessoa * p;
p=malloc(...)
Normalmente o malloc no retorna um
ponteiro sobre uma estrutura. Isto pode
causar um warning.
Uma maneira correta de escrever :
p=(Pessoa*)malloc(sizeof(Pessoa))
Uma outra soluo :
Pessoa * malloc();
239
Exerccio
Defina a funo proximo_aniv que pega
em entrada a data de nascimento de uma
pessoa e retorna uma estrutura designando a
data de seu prximo aniversrio.
240
data * proximo_anniv (data * p)
{
data * anniv;
anniv=(data*)malloc(sizeof(data));
anniv->ano=p->ano + 1;
anniv->mes=p->mes;
anniv->dia=p->dia;
return (anniv);
}
data d_nasci,d_anniv; ...
d_anniv=proximo_anniv(&d_nasci);
241
Criao de Listas
typedef struct {
char nome[20];
int peso;
Pessoa * seguinte;
} Pessoa;
Cabea
nome,peso
next
nome, peso
next
nome, peso
NULL
...
242
Pessoa * cabeca,pant,patu; char resp;
patu=(Pessoa *)malloc(sizeof(Pessoa));
patu->peso=30; ...
cabeca=patu;
puts("mais uma pessoa (s/n): "); resp=getch();
while (toupper(resp)!=N)
{
pant=patu;
patu=(Pessoa *)malloc(sizeof(Pessoa));
... /* leitura dos dados da nova pessoa */
pant->seguinte=patu; patu->seguinte=NULL:
puts("mais uma pessoa (s/n): ");resp=getch();
}
243
Modos FIFo Vs. LIFO
Existe dois modos para a criao das listas:
FIFO: First In First Out
LIFO: Last In First Out
Exerccio:
1. Qual o modo de criao de listas
aplicado no cdigo da pgina anterior?
2. Cria uma lista usando o outro modo.
244
Listas
Conjunto de elementos individualizados
em que cada um referencia um outro
elemento distinto como sucessor
245
Listas
Lista de Tarefas
Comeo em 3
Item Prximo
1. Pagar as contas no banco 6
2. Comprar os livros na livraria 4
3. Deixar o carro no estacionamento 8
4. Pegar algumas fitas na videolocadora Final
5. Enviar carta pelo correio 1
6. Buscar as fotos reveladas 2
7. Autenticar documentos no cartrio 5
8. Passa na banca de jornais 7
246
Insero no meio da Lista
Farmcia (9)
Foto (6) Livraria (2)
Antes
247
Insero no meio da Lista
Farmcia (9)
Foto (6) Livraria (2)
1 passo
248
Insero no meio da Lista
Farmcia (9)
Foto (6) Livraria (2)
2 passo
249
Insero no meio da Lista
Inserir o item farmcia entre Foto e
Livraria
1 Passo
lista[9].prox = lista[6].prox;
2 Passo
Lista[6].prox = 9;
250
Insero no fim da Lista
Farmcia (9)
Locadora (4) 0
Antes
251
Insero no fim da Lista
Farmcia (9)
Foto (6) 0
1 passo
252
Insero no fim da Lista
Farmcia (9)
Foto (6) 0
2 passo
253
Insero no fim da Lista
Inserir o item farmcia depois de
locadora
1 Passo
lista[9].prox = lista[4].prox;
2 Passo
Lista[4].prox = 9;
254
Insero no incio da Lista
Farmcia (9)
comeo Estacionam (3)
Antes
255
Insero no incio da Lista
Farmcia (9)
comeo Estacionam (3)
1 passo
256
Insero no incio da Lista
Farmcia (9)
comeo Estacionam (3)
2 passo
257
Insero no fim da Lista
Inserir o item farmcia no inicio da
lista (antes do primeiro item)
1 Passo
lista[9].prox = comeco;
2 Passo
comeco = 9;
258
Insero em uma lista
void insere(int novo, int antecessor)
{
lista[novo].prox = antecessor;
antecessor = novo;
}
259
Remoo em uma Lista
Farmcia (9)
comeo Estacionam (3)
Antes
260
Remoo em uma Lista
Farmcia (9)
comeo Estacionam (3)
1 passo
261
Remoo em uma lista
void remove(int velho, int antecess)
{
antecess = lista[velho].prox;
}
262
Filas (FIFO)
tambm uma Lista
Regra: todo o elemento que entra na
lista, entra no final e todo o elemento
que sai da lista, sai do incio dela.
FIFO (First In, First Out)
263
Filas (FIFO)
#define MAX 100
char *p[MAX]; int rpos=0, spos=0;
void armazena(char *c) {
if (spos==MAX) {
printf(Lista Cheia\n);
else
p[spos] = c;
spos++;
}
}
264
Filas (FIFO)
char *retira()
{
if (rpos==spos)
printf(Sem eventos\n);
return NULL;
else
rpos++;
return(p[rpos-1]);
}
265
PILHA (LIFO)
o inverso de uma fila
Regra: todo o elemento que entra na
lista, entra no final e todo o elemento
que sai da lista, sai do final dela.
ltimo a entrar, primeiro a sair
LIFO (Last In, First Out)
push/pop (empilha/desempilha)
266
PILHA (LIFO) - vetor
int p[100], top=0;
void push(int i)
{
if (top>=100)
printf("pilha cheia\n");
else {
p[top] = i;
top++;
}
}
267
PILHA (LIFO) - vetor
int pop();
{
top--;
if (top<0) {
printf("pilha vazia");
return 0; }
else
return(p[top]);
}
268
PILHA (LIFO) - ponteiro
int *p, *top, *b;
p = (int*)malloc(MAX*sizeof(int));
top = p;
b = p+MAX-1;
269
PILHA (LIFO) - ponteiro
void push(int i)
{
if (p>b)
printf("pilha cheia\n");
else {
*p = i;
p++;
}
}
270
PILHA (LIFO) - ponteiro
int pop();
{
p--;
if (p<top) {
printf("pilha vazia");
return 0; }
else
return(*p);
}
271
rvores Binrias
Rapidez na pesquisa, incluso e
excluso (qdo ordenadas)
info
info info
0 0 0 0
272
rvores - conceitos
Raiz
Ns
N terminal
Sub-rvore
Altura
273
Transversalizao
d
b
a c
f
e g
Ordenada a b c d e f g
Preordenada d b a c f e g
Ps-ordenada a c b e g f d
274
Unies de Tipos
275
Objetivo
Todas variveis que nos vimos at agora
possuam um nico tipo.
As vezes interessante atribuir vrios tipos
a uma varivel (uma mesma zona memria).
Isto pode ser feito atravs do mecanismo
de unies de tipos usando a palavra chave
union.
Portanto, uma varivel teria, a um dado
instante, um nico tipo, porm pode mudar.
276
Declarao
Exemplo:
/* declarao de um tipo que una os inteiros e os reais */
typedef union {
int i;
float f;
} nmero;
numero n;
Podemos ento escrever:
n.i=20; /* para atribuir um inteiro */
n.f=3.14159; /* para atribuir um real
*/
277
Observao
A declarao parecida s estruturas, mas
nas unies somente um campo atribudo
um valor.
O problema que nos no podemos saber a
um dado instante do programa, qual o tipo do
atual valor da varivel.
Por isso que na prtica a unio associada a
um indicador de tipo (o tipo atual) e os dois so
combinados em uma estrutura:
278
Utilizao Prtica das Unies
#define INTEIRO 0
#define REAL 1
typedef struct
{
int tipo_var;
union
{
int i;
float f;
} nmero;
} aritmtica;
279
Utilizao Prtica das Unies
/* declarao */
aritmtica a1,a2;
a1.tipo_var=INTEIRO;
a1.tipo_var=REAL
a1.nmero.i=10;
a1.nmero.i=10;
280
Facilitar o acesso aos campos
O acesso aos campos da unio dentro da
estrutura no muito prtico:
a1.nmero.i=10;
Isto pode ser resolvido usando as substituies e
o define:
#define I nmero.i;
#define R nmero.f;
Agora podemos escrever:
a1.I=10;ou a2.R=8.5;
281
Arquivos
282
Streams
Stream de texto
Sequncia de caracteres
Stream binria
Sequncia de bytes com uma
correspondncia de 1 para 1 com aqueles
encontrados no dispositivo externo
283
Funes mais comuns
Nome
Funo
fopen()
Abre um arquivo
fclose()
Fecha um arquivo
putc(),
fputc()
Escreve um caractere em um
arquivo
getc(),
fgetc()
L um caractere em um arquivo
#include <stdio.h>
284
Funes mais comuns
Nome Funo
fseek() Posiciona o arquivo em um bytes
especfico
fprintf() = printf console
fscanf() = scanf console
feof() Final de arquivo?
ferror() Ocorreu um erro?
rewind() Indicador de posio no incio do
arquivo
remove() Apaga um arquivo
285
Ponteiro de arquivo
Ponteiro para informaes que
definem vrias coisas sobre o
arquivo:
Nome, Status, Posio atual, ...
Ponteiro do tipo FILE
FILE *fp;
286
Abrindo um arquivo
FILE *fopen(nomearq, modo);
fopen devolve um ponteiro de
arquivo (em caso de erro o ponteiro
retornado nulo)
287
Abrindo um arquivo
r
w
a
rb
wb
ab
r+
w+
a+
r+b
w+b
a+b
288
Abrindo um arquivo
file *fp;
if ((fp=fopen(test,w))==null)
{
printf(no pode ser aberto);
exit(1);
}
289
Fechando um arquivo
Funo fclose()
Exite uma quantidade mxima de
arquivos que podem ser abertos
FOPEN_MAX (exemplo: 20)
290
Lendo / Escrevendo
void carrega_arquivo(char s[10000],
char nome_arquivo[1000]) {
FILE *fp; int i=0;
if ((fp =
fopen(nome_arquivo,"r"))==NULL) {
printf("erro\n");
exit(1); }
for (i=0; i<9999 && s[i]!=EOF;i++)
s[i] = getc(fp);
fclose(fp); }

Anda mungkin juga menyukai