You are on page 1of 76

Algoritmos e estruturas de dados:

partes centrais de qualquer software

Escolher a soluo mais adequada


Entender os compromissos de diferentes

estruturas de dados
Entender os limites do computador

Tipos abstratos de dados


Anlise de algoritmos
O(n), O(log(n)), etc

Estruturas de dados
Listas, filas, pilhas e rvores

Parte 2
Prova 2
Trabalho prtico 2

Mtodos de ordenao
Quicksort, heapsort, etc

Parte 1
Prova 1
Trabalho prtico 1

Mtodos de pesquisa
Hashing, rvores balanceadas

Parte 3
Prova 3
Trabalho prtico 3

Projeto de Algoritmos
Nvio Ziviani

Introduction to Algorithms
Cormen, Leiserson, Rivest, Stein

Algorithms
Robert Sedgewick e Kevin Wayne

The Art of Computer Programming


Volumes 1 e 3
Donald Knuth

3 provas (20+20+20 = 60 pontos)


1 prova suplementar

4 trabalhos prticos (4+10+10+16 = 40 pts)


Implementao
Documentao
Teste

3 listas de exerccios (1+1+1 = 3 pontos)

Pgina Web da disciplina


http://www.dcc.ufmg.br/~cunha/

Linguagem de programao: C
CodeBlocks
GCC

Sistema operacional recomendado: Linux


Os trabalhos prticos precisam rodar no Linux

Alta carga extra classe

Eficincia
Construes similares a instrues de mquina

Acesso direto memria


Portabilidade
De microcontroladores a supercomputadores

Poucos requisitos para execuo


Biblioteca padro limitada

Software de sistema ou de base


Linux
Gnome

Python, Perl, PHP, GCC


Bibliotecas
GNU Scientific Library
Partes do Matlab

Vrias aplicaes

Incluso de cabealhos
Declaraes globais
Definies de funes
#include <stdio.h>
char *mensagem = hello, world!\n;
int main(void) {
puts(mensagem);
return 0;
}

data.h

struct date {
int day; int month;
int year;
#include data.h
}

data.c

Compilador

struct data create(void)


struct date create(void);
{
int week_of_year(struct date d);
...
}
int semana_do_ano(struct data d)
{
...
}

date.h

...

data.o

data.h

struct date {
int day; int month;
int year;
}#include data.h

principal.c

Compilador

struct
int main(int
date create(void);
argc, char **argv)
int
{ week_of_year(struct date d);
...
}

date.h

principal.o
data.o

Ligador

date.o

calendrio.exe

main.o

Economize tempo de depurao tratando


todos os avisos do compilador
Muitas vezes a mensagem de erro no reflete o

que est ocorrendo; observar as redondezas da


linha em que o erro/warning foi indicado
[debian:~/prof/aeds2/src]% gcc Wall c data.c
data.c: In function main:
data.c:12: warning: return with no value,
in function returning non-void
data.c:11: warning: hoje is used
uninitialized in this function

Identificadores de funes e variveis


Letras, nmeros, e underscores
No podem comear com nmero

Palavras
reservadas

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

inline

restrict

Tipos inteiros
char, short, int, long, long long

Tipos de ponto flutuante


float, double, long double

void
Arranjos
Estruturas
Ponteiros

type_sizes
type_limits
float_precision
ascii_table

Aritmticos
x + y, x - y, x * y, x / y, x % y, -x

Incremento e decremento
x++, ++x, y--, --y

Comparao
x > y, x >= y, x < y, x <= y, x == y, x!= y

Lgicos
!x, x && y, x || y

Binrios
x & y, x | y, x ^ y, ~x, x << y, x >> y

Atribuio
x = y, x += y, x |= y, x <<= y, etc.

Endereamento de memria
&x, *x, x[y], x.campo, x->campo

Converso
(int)x, (double)x

Condicional
x ? y : z

sizeof
sizeof(x), sizeof(double)

Precedncia
1 << 2 * 3 % 4 ^ 5 6 && 7

Sequncia de elementos de um nico tipo


Tamanho fixo
Sem checagem de limites

Opcional: inicializao durante a declarao


Impossvel atribuir a um arranjo depois da declarao
int primos[7];
int primos[7] = {2, 3, 5, 7, 11, 13, 17};

primos
2

11 13 17

double identidade[4][4] = {{1, 0, 0, 0}, {0, 1, 0, 0},


{0, 0, 1, 0}, {0, 0, 0, 1}};

Alocao linear
Compilador converte indces para a posio do

elemento referenciado
identidade
1

identidade[x][y] = valor do elemento na posio x*4 + y


identidade[2][2] = dcimo valor = 1

Um string termina com o caractere nulo


\0

Um string num arranjo de 80 caracteres


char string[80] = hello world!

10 11 12 13 14
d

\0

Strings inicializados na declarao


char string[] = hello world!
O tamanho do arranjo definido

automaticamente pelo compilador

79
...

...

Copiar um string: strcpy, strncpy


Funes com n no nome recebem o tamanho do

arranjo como parmetro


Evita erros caso o string no caiba no arranjo

Concatenar strings: strcat, strncat


String de destino tem que ter espao

Comparar strings: strcmp, strncmp


Comparar strings com == s compara a posio dos

arranjos, no o contedo

Tamanho de um string: strlen


Duplicar um string: strdup

Converter string para inteiros


int atoi(const char *string)
long atol(const char *string)
long long atoll(const char *string)

Converter de string para ponto flutuante


double atof(const char *string)

array_boundaries1
array_boundaries2
string_cmp
string_gotchas

Combinam conjunto de dados relacionados

struct cliente {
char nome[48];
long long cpf;
long telefone;
struct endereco
residencial;
...
};

struct cliente cl;


cl.cpf = 65423423123;
sprintf(cl.residencial.rua,
Rua dos Goitacases);
cl.residencial.numero = 1325;
struct endereco end = {
Rua dos Goitacases, 1325 };

Campos armazenados em sequncia


Possvel incluso de espaamento pelo compilador

struct_static

Referncia para um objeto na memria


Vrios usos:
Manipulao de dados
Exemplo: ordenar um arranjo de estruturas grandes
Passagem de parmetro por referncia

Declaraes:

int i = 10;
int * ponteiro = &i;
int ** ppp = &ponteiro;

Varivel

Posio

Valor

0x80

10

ponteiro

0x84

0x80

ppp

0x88

0x84

Operadores & e *
Endereo de uma varivel um ponteiro para
aquela varivel
Acessar o valor da varivel apontada
int x = 10;
int y;
int * ponteiro = &x;
y = *ponteiro + 1; // y = x + 1 = 11
*ponteiro = 20; // x = 20

Nenhum ponteiro vlido tem o valor NULL


NULL no pode ser acessado
Falha de segmentao

til para denotar um ponteiro no inicializado


ou condies de erro

int * ponteiro;
/* ponteiro tem um valor
* aleatrio, no sabemos
* para onde ele aponta. */
ponteiro = NULL;
fatores(ponteiro);

int * fatores(int * p)
{
if(!p) { return NULL; }
// calcula fatores primos
...
}

No existe objeto com tipo void


Um ponteiro para void como um coringa,
pode apontar para qualquer tipo de objeto

int i;
int * int_ptr;
void * void_ptr;
double * double_ptr;
int_ptr = &i;
void_ptr = int_ptr; // OK
double_ptr = int_ptr; // !OK
double_ptr = void_ptr; // OK
/* Qual o problema com
* double_ptr? */

Varivel

Posio

Valor

0x80

10

int_ptr

0x84

0x80

void_ptr

0x88

0x80

double_ptr

0x8c

0x80

Declarao e inicializao normal

struct data { int dia; int mes; int ano; };


struct data d1;
struct data *ptr = &d1;
int i = 0;

Acesso aos campos

(*ptr).dia = 8;
(*ptr).mes = 3;
(*ptr).ano = 2012;
ptr->dia = 8;
ptr->mes = 3;
ptr->ano = 2012;

Varivel

Posio

Valor

d1.dia

0x80

d1.mes

0x84

d1.ano

0x88

2012

ptr

0x8c

0x80

0x90

Declarao
Tipo de retorno, nome, parmetros
double pow(double x, double y)

Em cabealhos .h para funes externas


Em arquivos .c para funes auxiliares (internas)

Definio

Em arquivos .c
Corpo da funo
double pow(double x, double y)

{
}

...

C passa parmetros por valor


Modificaes do valor de um parmetro no afeta

a varivel original (fora da funo)


int incrementa(int x) {
x = x+1;
return x;
}
int main(int argc, char **argv)
{
x = 1;
y = incrementa(x);
printf(%d %d\n, x, y);
...

Variedade de utilidades
Declarao
int (*comparador)(void *e1, void *e2);

Inicializao
Nome da funo convertido em ponteiro

int compara_dados(void *e1, void *e2) { ... };


int main(void) {
int (*compara)(void *e1, void *e2) = compara_dados;

Passando como parmetro

void ordena(void *dados, int nelem,


int (*comparador)(void *e1, void *e2));

func_params
struct_func_params
test_write_to_str

Prefervel sempre que no soubermos quanta


memria um programa utilizar
Alocao esttica fixa
Alocao dinmica permite utilizar a quantidade

necessria de memria sem desperdcios

Alocar um novo bloco de memria


malloc(), calloc()

Redimensionar um bloco j alocado


realloc()

Liberar um bloco alocado


free()

malloc aloca um bloco de size bytes


O contedo do bloco alocado indeterminado
Retorna um ponteiro para void
O programador decide como usar o bloco alocado

Retorna NULL em caso de erro

int *primos = malloc(7 * sizeof(int));


if(!primos) { perror(NULL); exit(1); }
char *buffer = malloc(64);
if(!buffer) { perror(NULL); exit(1); }
double *fracoes = malloc(8*sizeof(double));
malloc(64);
if(!fracoes) { perror(NULL); exit(1); }
memset(fracoes, 0, 8*sizeof(double));

calloc aloca um bloco com espao para


count objetos de tamanho size bytes
O bloco alocado inicializado com zero

int *primos = calloc(7, sizeof(int));


if(!primos) { perror(NULL); exit(1); }
char *buffer = calloc(64, sizeof(char));
if(!buffer) { perror(NULL); exit(1); }
double *fracoes = calloc(8, sizeof(double));
if(!fracoes) { perror(NULL); exit(1); }
memset(fracoes, 0, 8*sizeof(double));

Redimensiona o bloco de memria apontado


por ptr para size bytes
Mantm o contedo do bloco apontado por ptr

(limitado pelo tamanho do novo bloco)


O local do novo bloco de memria pode mudar
Mesmo se o novo bloco for menor que o anterior!
int *primos = calloc(7, sizeof(int));
if(!primos) { perror(NULL); exit(1); }
realloc(primos, 5*sizeof(int));
// BUG
primos = realloc(primos, 5*sizeof(int)); // OK
if(!primos) { perror(NULL); exit(1); }

Libera o bloco de memria apontado por ptr


Chamar free mais de uma vez pra um mesmo

bloco de memria um bug


free s pode ser chamada em ponteiros
retornados por malloc, calloc e realloc.
char * montar_string(struct endereco e) {
char *string = malloc(128);
if(!string) { perror(NULL); exit(1); }
// montar string ...
return string;
}

char * exemplo(char parametro[])


{
int i; char estatico[80];
char *dinamico = malloc(80);
Varivel

Posio

Valor

parametro

0x7c

0x480

0x80

estatico[0]

0x84

...

...

estatico[79] 0xd3

dinamico

0x884

0xd4

Varivel

Posio Valor

dinamico[0]

0x884

dinamico[1]

0x885

...

...

dinamico[79] 0x8d3

dyn_alloc
pointer_arith

Rotinas de entrada e sada no fazem parte


da linguagem
Disponveis em bibliotecas que acompanham
os compiladores
Padronizadas
Em C, so definidas no cabealho stdio.h

formato especfica como os valores devem


ser impressos na sada.
printf(X = %d, x);

printf(Area: %f\n, PI*r*r);


printf(Nome: %s, aluno.nome);

Existem vrios caracteres de controle


Retorna o nmero de converses impressas
til para checar erros

%[opes][largura mnima][.preciso][tamanho]converso
printf(valor do float
doublena
naposio
posio%p
%p==%f\n,
%lf\n,
%+06.2lf\n,
ptr,
ptr,
*ptr);
*ptr);
ptr, *ptr);
tamanho

tamanho

converso

zeros esquerda

hh

char

char

alternativa

short

int

alinhar esquerda

long

unsigned int

mostrar sinal positivo

ll

long long

int, hexadecimal

espao para sinal positivo

long double

float

agrupar milhares

size_t

float, cientfico

digitos alternativos

ptrdiff_t

float, e ou f

intmax_t

ponteiro

string

sinal percentual

Caracteres especiais e reposicionamento do


cursor

printf(barra invertida \\\n);


printf(aspas duplas \\n);
printf(tab\ttab\ttab\tnova linha\ntexto\n);

scanf o inverso do printf:


l dados do terminal
Mesmos cdigos de converso
Mesmas sequncias de escape

Passar um ponteiro para a varivel que voc


quer inicializar
int nlados = 0;
float lado = 0;
scanf(%f %d\n, &lado, &nlados);
perimetro = lado * nlados;

Observe que scanf interrompe a leitura de


um string (%s) quando encontra um branco
Especificadores de tamanho e filtro

%[aeiou]s l apenas vogais

Para na primeira consoante, nmero, espao, pontuao, etc

%[0123456789]s l apenas nmeros


%60s l apenas 60 caracteres
%60[^0123456789]s l at 60 caracteres parando
quando encontrar um nmero

char buffer[80];
scanf(%79s, buffer);

getchar l um nico caractere do terminal


putchar(int c) imprime o caractere
com valor c no terminal

Mesma coisa, s precisamos passar o


manipulador do arquivo como parmetro
FILE *entrada;

FILE *saida;
...
fscanf(entrada, %79s, buffer);
char c = fgetc(entrada);
fputc(c, saida);
fprintf(saida, X = %d, x);

FILE * fopen(char *nome, char *modo)


Abre o arquivo com o dado nome
modo pode ser:
r para leitura, w para escrita, rw para leitura e escrita
Se o arquivo j existir, podemos usar a para adicionar ao arquivo

Sempre teste se o retorno nulo, pois podem ocorrer erros


Arquivo ou caminho no existente, permisses insuficientes, etc.

int fclose(FILE *arquivo)


Fecha o arquivo apontado por arquivo

FILE *arquivo = fopen(C:\Users\Cunha\Desktop\teste.txt, w);


if(!arquivo) { perror(NULL); exit(EXIT_FAILURE); }
fprintf(arquivo, hello arquivo!\n);
fclose(arquivo);

printf e fprintf so idnticas, s operam sobre


manipuladores de arquivos diferentes
printf sempre imprime na sada padro (terminal)
fprintf recebe o arquivo onde imprimir como parmetro

O manipulador do arquivo correspondente sada padro o

stdout, e o manipulador da entrada padro o stdin


fprintf(stdout, imprimindo no terminal\n);

Cuidado ao terminar de ler um arquivo


Use int feof(FILE *arquivo)para testar

se j leu o arquivo at o fim


feof retorna falso se o arquivo ainda no tiver
terminado
feof s retorna verdadeiro depois que voc tentar ler
aps o arquivo ter terminado

Saber a posio atual do arquivo


long ftell(FILE *arquivo)

Mudar para uma dada posio no arquivo


int fseek(FILE *arquivo,

int base, int distancia)


Onde base pode ser:
SEEK_SET, o comeo do arquivo
SEEK_CUR, a posio atual no arquivo
SEEK_END, o final do arquivo

write_test_file
feof_scanf_test

int main(int argc, char *argv[]) { ... }

argv um arranjo de strings, um parmetro em

cada ndice do arranjo


argc o nmero de parmetros em argv
argv[0] sempre o nome do executvel
Logo, argc >= 1

Para processamento avanado de


parmetros, use getopt()
Parmetros em qualquer ordem, opcionais, etc.
ls -al --color=auto --sort=x

cmdline_params (CodeBlocks)
crypto

Pequeno esforo, grande impacto

Cdigo mais legvel


Ajuda o entendimento das idias
til quando voc for ler o cdigo 6 meses depois
til para outras pessoas

Cdigo com menos erros


Economizar tempo e ter menos dor de cabea

Em AEDS2: ajuda entendimento das idias e


correo dos trabalhos

Reala estrutura lgica do cdigo

Em geral, indenta-se com tabulao (tab)


Em geral um tab corresponde a 8 espaos, mas

configurvel na maioria dos editores

static char * concat (char *s1, char *s2) { while (x == y) { something (); somethingelse (); } finalthing (); }

static char * concat(char *s1, char *s2)


{
while(x == y) {
something();
something_else();
}
final_thing();
}

K&R

static char *
concat(char *s1, char *s2)
{
while(x == y)
{
something();
something_else();
}
final_thing();
}

Allman

static char *
concat(char *s1, char *s2)
{
while(x == y)
{
something();
something_else();
}
final_thing();
}

GNU

Facilitam a compreenso do cdigo, mais


importantes para cdigo complexo

Cdigo bem escrito no depende muito de


comentrios

Comentrio errado pior do que nenhum


comentrio
Revisar comentrios quando o cdigo mudar

No incio de um mdulo
Descrever variveis globais ou importantes
Em funes para explicar os parmetros, o
tipo de retorno, e o que a funo faz
No explicar como a funo faz a tarefa, cdigo

deve ser claro o bastante

Indicar invariantes de loops


No comentar o bvio

DUH:
i += 1; // incrementa i.
OK:
i += 1; // compensar borda.

Escolher bons identificadores ajudam a


compreenso do cdigo
void ordena(int *vetor);
void processa(int *vetor);
double media(int *vetor);

Mesma coisa para variveis


Variveis auxiliares podem receber nomes simples, mas
sem exagerar
Indices: i, j, k
Variveis tipo ponto flutuante: x, y, z
Strings: s1, s2, str

Se houver, preferir o estilo que j estiver em uso

Underscore:
int num_clientes;
struct list *lista_alunos;

CamelCase:
int numClientes;
struct lista *listaAlunos;

No usar nmeros mgicos no cdigo


Valores podem precisar ser modificados
Nmeros mgicos no tm significado
Usar #define para dar nome a constantes
Nomes em maisculas
#define PI 3.14159
#define TAMANHO_MAX_LINHA 256

char * le_linha(FILE *entrada) {


char *linha = malloc(TAMANHO_MAX_LINHA);
...
return linha;
}

Particionamento de um programa
Um mdulo geralmente um par de arquivos
modulo.c contm a implementao das funes
modulo.h contm a declarao das funes e

tipos de dados; importado por outros mdulos

Outros programadores s precisam saber o


que o mdulo faz, no como ele funciona
Procurar identificar mdulos independentes
para que eles possam ser reaproveitados

You might also like