Академический Документы
Профессиональный Документы
Культура Документы
e
Estruturas
de
Dados
II
Clodoveu
Davis
e
Gisele
Pappa
clodoveu@dcc.ufmg.br
glpappa@dcc.ufmg.br
Ementa
Tipos
Abstratos
de
Dados
(TADs)
TP0 5 ptos
Parte 1
Anlise
de
Algoritmos
Prova 1 11/09
O(n),
O(n
log
n),
)(n!),
...
Parte 2
Estruturas
de
dados
Prova 2 09/10
listas,
las,
pilhas
e
rvores
Mtodos
de
ordenao
quick,
heap,
merge,
select,
etc
Mtodos
de
pesquisa
hash,
rvores
binrias,
rvores
digitais
Parte 3
Prova 3 25/11
TP2 20 ptos
E terminar assim????
Avaliao
3
provas
(total
60
pontos)
2
trabalhos
prYcos
power
(total
40
pontos)
Implementao
Documentao
Teste
Moddle
Todas
informaes
relacionadas
ao
curso,
incluindo
notas
de
aulas,
estaro
disponveis
no
Moodle
Sistema
de
submisso
de
trabalhos
prYcos
PrYco
h`p://aeds.dcc.ufmg.br
Detalhes
Linguagem:
C
Socware
Recomendado:
CodeBlocks
Instrues
de
instalao
no
Moodle
Programao em C
Clodoveu
Davis
Gisele
L.
Pappa
Tpicos
Indentao
Comentrios
Modularizao
Compilao
e
Debug
Entrada
e
sada
Vetores
e
Strings
Passagem
de
parmetros
Structs
Boas
PrYcas
Com
um
pequeno
esforo
extra,
programas
escritos
em
C
podem
se
tornar
mais
legveis
e
mais
facilmente
debugveis
No
caso
de
disciplinas
de
programao,
isso
ainda
ajuda
no
entendimento
das
idias
e
na
correo
de
trabalhos
Indentao
usual
empregar
TABS
para
indicar
blocos
de
programao
Em
geral,
1
tab
equivale
a
8
espaos,
MAS
NO
USAR
ESPAOS
para
alinhar
H
vrios
esYlos
Quando
o
bloco
longo,
usual
colocar
um
pequeno
comentrio
aps
o
fechamento
indicando
o
que
est
sendo
fechado
Indentao
K&R:
Kernighan
&
Ritchie
Indentao
1TBS:
One
True
Brace
Style
Indentao
Allman
Comentrios
Importantes
para
compreenso
do
cdigo
Mais
importantes
em
cdigo
mais
complexo
teis
para
explicar
o
contedo
de
variveis,
mas
no
subsYtuem
um
bom
critrio
de
atribuio
de
nomes
No
exagerar!
Comentrios
No
incio
de
cada
mdulo
de
cdigo
(arquivos
.c,
.h)
Uma
linha
em
cada
funo,
explicando
o
que
ela
faz
No
necessrio
explicar
COMO
ela
faz,
o
cdigo
deve
ser
claro
o
bastante
para
permiYr
esse
entendimento
em
uma
funo
razoavelmente
pequena
Se
necessrio,
considerar
a
quebra
em
outras
funes
Comentrios
No
incio
de
um
bloco/arquivo
fonte
Comentrios
Em
funo
(simples)
Comentrios
Em
funes
(arquivo
.h)
Comentrios
Em
variveis
Em
structs
Comentrios
No
m
de
um
bloco
de
programa
No
cdigo
Modularizao
Planejar
a
quebra
de
um
programa
em
mdulos
Um
mdulo
no
signica
necessariamente
um
arquivo
fonte;
muitas
vezes,
um
par
de
arquivos
.c
/
.h
Existe
sempre
um
arquivo
fonte
para
o
programa
principal
(main),
e
outros
para
funes
adicionais
ou
componentes
Modularizao
Modularizao
Modularizao
Modularizao
Modularizao
transformao em biblioteca
Ymer.lib
Constantes
e
#dene
No
usar
nmeros
mgicos
no
cdigo
Algumas
constantes
usadas
no
programa
podem
ter
que
ser
modicadas,
e
mais
fcil
fazer
isso
em
um
lugar
s
Sempre
que
for
tornar
o
cdigo
mais
legvel,
usar
#dene
para
dar
um
nome
constante
Em
geral,
nomes
de
constantes
so
em
maisculas
#define PI 3.141592
#define MAX_VETOR 1000
Nomes
de
variveis
Algumas
variveis
merecem
nomes
signicaYvos:
MAX_VETOR, numClientes, listaAlunos
Variveis
auxiliares
em
geral
recebem
nomes
curtos:
i, j, aux, x
Cuidado
para
no
fazer
confuso
No
abusar: i, ii, iii, aux1, aux2,
aux3...
Variveis
inteiras:
i, j, k
Variveis
reais:
x, y, z
Strings:
s1, s2
Booleanas:
nome
do
teste
(existe, valido,
ocorre)
Nomes
de
variveis
EsYlos
variados:
S
minsculas
(i, num, conta)
S
maisculas
(constantes:
PI, E, MAX)
CamelCase
(numMat, anguloEntrada)
Indicao
do
Ypo
no
incio
do
nome
(iNum,
iValor, fRaio, fAltura, dVolume)
Organizao
e
limpeza
Procurar
dar
um
aspecto
organizado
ao
cdigo,
ajuda
na
compreenso
Entender
o
cdigo
fonte
como
um
instrumento
de
comunicao
Comentar
excessivamente
cdigo
mal
escrito
no
ajuda
Dar
nomes
adequados
a
variveis
ajuda
bastante
Parnteses
e
espaamento
Usar
espaos
antes
de
parnteses,
depois
de
vrgulas,
ao
redor
de
operadores
binrios
if (x == 10) y = 5;
for (i = 0; i < 10; i++) {
x += a;
a = f(b);
}
Correo
e
robustez
Testes:
prever
todo
Ypo
de
problema
e
variaes
na
entrada
de
dados
Limites
de
vetores
Valores
inteiros
e
de
ponto
utuante
Contadores
e
incremento
Testes
de
m
de
arquivo
Teste
de
disponibilidade
de
memria
para
alocao
Compilao
LER
as
mensagens
de
erro
e
ENTENDER
a
origem
do
problema
Warnings:
indicam
problemas
potenciais,
devem
ser
resolvidos
Muitas
vezes
a
mensagem
de
erro
no
reete
o
que
est
ocorrendo
Observar
a
linha
em
que
o
erro
foi
indicado,
a
linha
anterior,
o
bloco
de
cdigo
em
que
ocorreu,
e
o
corpo
da
funo
em
que
ocorreu
Debugger
Ajuda
a
acompanhar
os
valores
das
variveis
ao
longo
da
execuo
Observar
o
valor
de
variveis
(watches)
Posicionar
pontos
de
interrupo
(breakpoints)
Executar
passo
a
passo
Vide
http://wiki.codeblocks.org/index.php?title=Debugging_with_Code::Blocks
Documentao
do
CodeBlocks
http://wiki.codeblocks.org/index.php?title=Main_Page
ENTRADA E SADA
I/O
em
C
Formalmente,
roYnas
de
entrada
e
sada
no
fazem
parte
da
linguagem,
e
sim
de
bibliotecas
que
acompanham
os
compiladores
Felizmente,
so
padronizadas
Exige-se
a
linha
#include
<stdio.h>
para
us-las
I/O
em
C
prin(string
[,
valor
,
valor,
...]);
O
string
contm
uma
mscara
(template)
com
lacunas
reservadas
para
os
valores
que
sero
impressos
Pode
no
exisYr
lacuna
prin
Especicadores
de
formato
%c
(char)
%s
(string)
%d
(int)
%ld
(long
int)
%f
(oat)
%lf
(double)
%e
(oat
notao
cienca)
%g
(e
ou
f,
ou
seja,
notao
cienca
se
necessrio)
prin
Especicao
completa
Caracteres
de
escape
Acrescentados
mscara
para
provocar
reposicionamento
do
cursor
\n:
nova
linha
\t:
tabulao
\r:
backspace
\\:
caractere
da
barra
inverYda
Entrada
Com
mscara:
scanf(string,
*var
[,
*var,
...]);
Mesmos
especicadores
de
formato
do
prin
A
funo
precisa
receber
o
endereo
da
varivel
qual
o
valor
digitado
ser
atribudo
scanf(%d, &num)
scanf(%c%d, &letra, &num);
scanf(%c, &ch);
scanf(%s, s); // string
scanf(%13c, s); //le 13 caracteres
scanf( %c, &ch); //pula brancos
Entrada
Entrada
Observe
que
scanf
interrompe
a
leitura
de
um
string
quando
encontra
um
branco,
se
usado
com
%s
Uso
de
%[]:
%[aeiou]:
apenas
as
vogais
so
permiYdas
%[^aeiou]:
as
vogais
no
so
permiYdas
%[^\n]:
interrompe
quando
recebe
um
[enter]
%60[^\n]:
admite
at
60
caracteres,
e
para
quando
encontra
um
enter
Entrada
Linhas
inteiras:
gets(string)
L
uma
linha
inteira,
excluindo
\n,
e
coloca
\0
no
nal
Com
limite
de
tamanho:
fgets(string, tamMax, stdin)
Entrada
Caracteres
individuais:
getchar()
O
caractere
digitado
o
valor
de
retorno
da
funo
}!
VETORES E STRINGS
Vetores
Quando
se
declara
um
vetor,
o
valor
entre
chaves
indica
quantas
vezes
o
espao
de
memria
necessrio
para
o
Ypo
bsico
ser
alocado
int v[100]; // 100 * sizeof(int) = 200 bytes
long vl[200]; // 200 * sizeof(long) = 800 bytes
double z[1000]; // 1000 * sizeof(double) = 8000 bytes
Vetores
A
referncia
a
uma
posio
de
um
vetor
indica
o
clculo
de
uma
posio
de
memria
a
parYr
do
incio
do
vetor
float x[1000];
// x[20] est na posio x + 20*sizeof(float)
Vetores
C
NO
AVISA
NEM
PRODUZ
ERRO
QUANDO
O
LIMITE
DE
UM
VETOR
OU
MATRIZ
FOR
EXCEDIDO
y = x[2000]; // no d erro, mas vai acessar
// uma parte inesperada da memria
Matrizes
Strings
Um
string
um
vetor
do
Ypo
char
Para
manipulao
do
string,
atribuindo
e
recuperando
valores,
e
realizando
operaes
sobre
ele,
importante
entender
essa
caractersYca
Quando
o
contedo
de
um
string
no
ocupa
todo
o
espao
disponvel,
usa-se
um
caractere
\0
(ou
NULL,
cdigo
ASCII
0)
como
delimitador
Strings
Strings
constantes
aparecem
no
cdigo
entre
aspas
printf(%s, Bom dia!);
Strings
No
possvel
fazer
atribuies
diretas
para
strings
Usar
a
funo
strcpy
ou
a
funo
strncpy
Strings
Na
inicializao,
pode-se
usar
o
mesmo
recurso
disponvel
para
vetores
char nome[] = {A, n, a, \0};
Ou
char nome[] = Ana;
Strings
Como
o
nome
do
string
representa
o
endereo
onde
comea
o
string,
possvel
manipul-lo
diretamente
Cuidado!
Exemplo
char nome[] = Alexandre;
printf(%s\n, nome + 3); // imprime xandre
Strings
Funes
strlen(st):
retorna
o
comprimento
do
string
(com
exceo
do
\0)
strcat(st1,
st2):
concatena
o
s2
no
s1
(s1
tem
que
ter
espao)
strcmp(s1,
s2):
retorna
<0
se
s1
menor
que
s2,
==0
se
s1
igual
a
s2,
e
>0
se
s1
maior
que
s2
(ordem
alfabYca)
A
comparao
entre
strings
tambm
tem
que
ser
feita
caractere
a
caractere,
portanto
no
se
pode
usar
s1==s2;
isso
s
compara
os
endereos
Strings
strncat,
strncmp,
strncpy:
idem
aos
anteriores,
mas
especica
o
nmero
de
caracteres
que
sero
considerados
Strings
strtok:
extrai
tokens,
substrings
delimitados
Exemplo
long int num; char linha[256];
char *p1 = NULL;
while (!feof(infile)) {
fgets(linha, 256, infile);
p1 = strtok(linha, " \n"); //delim: branco ou fim de linha
while ((p1 != NULL) && (!feof(infile)))
{
num++;
fprintf(outfile, "%s\n", p1);
p1 = strtok(NULL, " \n");
}
}
printf("O arquivo de entrada tinha %ld palavras.\n", num);
fclose(infile);
Strings
Vetores
de
strings
podem
ser
criados
Exemplo
char DiaSemana[7][14] = {Domingo,
Segunda, Tera, Quarta,
Quinta, Sexta, Sabado};
...
printf(%s\n, DiaSemana[3]);
E
Java?
Em
java
no
existe
manipulao
explcita
de
apontadores.
Todo
objeto
criado
dinamicamente
(new)
e
as
variveis
apontam
para
os
objetos
Variveis
dos
Ypos
bsicos
so
alocadas
estaYcamente
(no
necesrio
o
new)
Alocao
Dinmica
A
memria
alocada
dinamicamente
acessada
atravs
de
Apontadores
(pointers)
que
na
verdade
so
variveis
que
armazenam
o
endereo
de
uma
rea
de
memria
A
memria
alocada
dinamicamente
faz
parte
de
uma
rea
de
memria
chamada
heap
Basicamente,
o
programa
aloca
e
desaloca
pores
de
memria
do
heap
durante
a
execuo
Algoritmos
e
Estrutura
de
Dados
II
Alocao
Dinmica
Memria Esttica
Heap
0x214
0x016 a
10
0x020 b
0x234
0x218
0x222
0x226
0x230
10
a um int
b um apontador para um int
0x234
0x238
0x242
0x246
Algoritmos
e
Estrutura
de
Dados
II
Apontadores
Notao
em
C
denio
de
p
como
um
apontador
para
uma
varivel
do
Ypo
T
T
*p;
Alocao
de
memria
para
uma
varivel
apontada
por
p
p
=
(T*)
malloc(sizeof(T));
Desalocao
de
memria
free(p);
Algoritmos
e
Estrutura
de
Dados
II
Endereo
da
Varivel
Endereo
do
primeiro
byte.
Exemplo
int i;
char c;
int v[5];
struct {
int x,y;
} p;
printf("%d\n",
printf("%d\n",
printf("%d\n",
printf("%d\n",
Algoritmos
e
Estrutura
de
Dados
II
Endereos Impressos:
2293612
&i);
&c);
&v);
&p);
2293611
2293552
2293544
P 8 bytes
P 8 bytes
Alocao
Dinmica
int *a, b;
...
b = 10;
a = (int *) malloc(sizeof(int));
*a = 20;
a = &b;
*a = 30; // qual o valor de b?
Algoritmos
e
Estrutura
de
Dados
II
Memria
Esttica
Heap
Alocao
Dinmica
int *a, b;
...
b = 10;
a = (int *) malloc(sizeof(int));
*a = 20;
a = &b;
*a = 30; // qual o valor de b?
Memria
Esttica
Heap
b 10
30
a
20
Algoritmos
e
Estrutura
de
Dados
II
Memria no foi
desalocada. O
espao continua
ocupado
Erros
Comuns
Esquecer
de
alocar
memria
e
tentar
acessar
o
contedo
da
varivel
Copiar
o
valor
do
apontador
ao
invs
do
valor
da
varivel
apontada
Esquecer
de
desalocar
memria
Ela
desalocada
ao
m
do
programa
ou
procedimento
funo
onde
a
varivel
est
declarada,
mas
pode
ser
um
problema
em
loops
Algoritmos
e
Estrutura
de
Dados
II
Vetores
e
Apontadores
Na
verdade,
em
C
todo
vetor
(mesmo
alocados
de
forma
estYca)
pode
ser
visto
como
um
apontador.
Pode
se
trabalhar
usando
ambas
notaes:
p
*p
equivalente
a
p[0]
6 4
0 1 ...
p
equivalente
a
&p[0]
*(p
+
i)
equivalente
a
p[i]
considerando
v
um
vetor
alocado
estaYcamente,
e
p
dinamicamente,
pode-se
fazer
p
=
v,
mas
no
v
=
p
(v
,
de
certa
forma,
um
ponteiro
constante)
Algoritmos
e
Estrutura
de
Dados
II
int**
result_matrix;
Matrizes
void free_matrix(int **matrix, int rows)
{
int i;
for(i=0; i<rows; i++)
{
free(matrix[i]);
}
free(matrix);
}
Realloc
3.14
2.718
5.0
20.0
5.0
?
a = 3.14;
printf("%f\n", a);
p = &a;
*p = 2.718;
printf("%f\n", a);
a = 5;
printf("%f\n", *p);
p = NULL;
p = (double *)malloc(sizeof(double));
*p = 20;
q = p;
printf("%f\n", *p);
printf("%f\n", a);
free(p);
printf("%f\n", *q);
Algoritmos
e
Estrutura
de
Dados
II
int a, b, i, v[10];
int *p;
b = 10;
p = &b;
a = *p + 100;
printf("%d\n", a);
a = *&b;
printf("%d\n", a);
for(i=0; i<10; i++)
v[i] = i;
p = v;
for(i=0; i<5; i++)
*(p+i) = 10*i;
p = p + 5;
*p = -5;
for(i=0; i<10; i++)
printf(%d,v[i]);
110
10
0
10
20
30
40
-5
6
7
8
9
Passagem
de
Parmetros
Em
pascal
e
C++,
parmetros
para
funo
podem
ser
passados
por
valor
ou
por
referncia
Por
valor:
o
parmetro
formal
(recebido
no
procedimento)
uma
cpia
do
parmetro
real
(passado
na
chamada)
Por
referncia:
o
parmetro
formal
(recebido
no
procedimento)
uma
referncia
para
o
parmetro
real
(passado
na
chamada)
As
modicaes
efetuadas
acontecem
no
parmetro
real
int main()
{
int a=0, b=0;
SomaUm(a, &b);
printf("Programa principal: %d %d\n", a,
b);
0 1
}
Algoritmos
e
Estrutura
de
Dados
II
Passagem
de
Parmetros
E
para
alocar
memria
dentro
de
um
procedimento?
Em
pascal,
basta
passar
a
varivel
(apontador)
como
referncia.
Em
C
tambm,
mas
como
no
h
passagem
por
referncia
as
coisas
so
um
pouco
mais
complicadas
void aloca(int *x, int n)
{
x=(int *)malloc(n*sizeof(int));
x[0] = 20;
}
int main()
Error!
{
Access Violation!
int *a;
aloca(a, 10);
a[1] = 40;
}
Algoritmos
e
Estrutura
de
Dados
II
Exerccios
1. Faa
um
programa
que
leia
um
valor
n,
crie
dinamicamente
um
vetor
de
n
elementos
e
passe
esse
vetor
para
uma
funo
que
vai
ler
os
elementos
desse
vetor.
Algoritmos
e
Estrutura
de
Dados
II
Respostas
(1)
void LeVetor(int *a, int n){
int i;
for(i=0; i<n; i++)
scanf("%d",&a[i]);
}
Respostas
(2)
typedef struct {
int a;
char *b;
} TRegistro;
Referncias
Mizrahi,
V.
V.
Treinamento
em
Linguagem
C.
Pearson,
2008.
Kernighan
B.W.,
Ritchie,
D.M.
C
A
linguagem
de
programao
(padro
ANSI).
Campus,
1989.
Vide
Moodle
para
links
(inclusive
cursos
online),
exemplos
e
exerccios