estrutura de dados ii carlos oberdan rolim ciência da computação sistemas de informação

41
Estrutura de dados II Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação

Upload: internet

Post on 18-Apr-2015

104 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Estrutura de dados II Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação

Estrutura de dados II

Carlos Oberdan Rolim

Ciência da ComputaçãoSistemas de Informação

Page 2: Estrutura de dados II Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação

Revisão

Ponteiros, passagem de parâmetros para funções,

alocação dinâmica e estruturas

Page 3: Estrutura de dados II Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação

Ponteiros

Page 4: Estrutura de dados II Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação

Ponteiros em Linguagem C

O Que é uma variável?

É uma área da memória do computador onde é armazenado um valor….

Exemplo 1:

int a = 1; Atribui ao endereço 1000 o valor 1

1000 1001 1002 1003

1

Variável Posição

a 1000

Page 5: Estrutura de dados II Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação

Ponteiros em Linguagem C

O Que É Um Ponteiro?

Um ponteiro é uma variável que aponta para outra variável. Isto significa que um ponteiro mantém o endereço de memória de outra variável. Em outras palavras, o ponteiro não contém um valor no sentido tradicional, mas sim o endereço de outra variável. Um ponteiro "aponta para" esta outra variável mantendo uma cópia de seu endereço

Convém dizer que a expressão “apontar para...” significa “armazenar o endereço de memória de...”

Como um ponteiro contém um endereço, e não um valor, terá duas partes. O ponteiro contém um endereço e o endereço aponta para um valor. Há o ponteiro e o valor para o qual ele aponta. Este fato pode ser um tanto confuso, até você se familiarizar com ele. Superada a etapa da familiarização, ele se torna extremamente eficaz.

Page 6: Estrutura de dados II Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação

Ponteiros em Linguagem C

Operadores relacionados a Ponteiros:

*(asterisco): informa que uma variável irá armazenar o endereço de outra variável;

ou:

Informa ao computador que vc deseja o valor que está no endereço armazenado;

- Pode ser lido como “no endereço”

q = *m; q recebe o valor armazenado no endereço m

& (e comercial): retorna o endereço de uma variável;

- Pode ser lido como “o endereço de”

m = &count; m recebe o endereço de count

Page 7: Estrutura de dados II Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação

Ponteiros em Linguagem C

int main() {

int i,j;

int *p;

p = &i;

*p=5;

j=i;

printf(("%d %d %d\n", i, j, *p);

return 0;

}

==> 5 5 5

Page 8: Estrutura de dados II Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação

Operadores de ponteiros

* (asterisco) indica que a variável é um ponteiro

tipo_dado *nome_ponteiro;

Ex:

int x;

int *pi; /* compilador sabe que pi é ponteiro */

/* pi é um ponteiro para inteiro */

Page 9: Estrutura de dados II Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação

Operadores de ponteiros

o operador “&” quando aplicado sobre uma variável retorna o seu endereço

Ex:

int x = 10, *pi;

pi = &x;

printf(“&x: %p pi: %p”, &x, pi);

=> &x: 0x03062fd8 pi: 0x03062fd8

Page 10: Estrutura de dados II Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação

Operadores de ponteiros

o operador “*” quando aplicado sobre um ponteiro retorna o dado apontado

Ex:

void main () {

int *tmp_ptr;

int x, y;

x = 10;

tmp_ptr = &x;

y = *tmp_ptr; /* (*tmp_ptr) = 10 */

}

tmp_ptr

x

y

0xABA0

0xABA2

0xABA0

10

10

Page 11: Estrutura de dados II Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação

Outro exemplo ilustrado

int i; int *p;

p = &i;

*p=5;

Page 12: Estrutura de dados II Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação

Relembrando...

operador *declara-se com *

int *xacessa-se (alterar, modificar, ler) também com *

*x = 10; // atribui o valor 10 ao local apontado pelo ponteiro ‘x’

printf(“%d”, *x); // imprime o valor armazenado no local apontado por ‘x’

observação: strings e vetores funcionam de forma diferente: um vetor ou string é um ponteiro por definição

operador &acessa (alterar, modificar, ler) o endereço de uma variável (que é um ponteiro)

Page 13: Estrutura de dados II Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação

Exemplo de uso

int a = 1; declara variavel inteiro com valor 1

int *pt_a; declara um ponteiro para um inteiro

pt_a = &a; ponteiro recebe o endereco da variavel a

printf(“%d”, *pt_a); imprime o valor apontado pelo ponteiro

Page 14: Estrutura de dados II Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação

Ponteirosponteiros são variáveis tipadas: (int *) ≠ (float *) ≠ (char *)

As variaveis ponteiro devem sempre apontar para os tipos de dados corretos. Uma variavel ponteiro declarada como apontador de dados inteiros deve sempre apontar para dados deste tipo.

Ex:

main() {

int *ip, x;

float *fp, z;

ip = &x; /* OK */

fp = &z; /* OK */

ip = &z; /* erro */

fp = &x; /* erro */

}

Page 15: Estrutura de dados II Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação

Ponteiros

espaço ocupado pelas variáveis

Ponteiro aponta para o tamanho segundo seu tipo

1 byte

(int *)

1 byte

(float *)

(char *)

Page 16: Estrutura de dados II Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação

Exemplo de uso

Exemplo:

int a = 1;

int *pt_a;

pt_a = &a;

1000 1001 1002 1003

1 1000

Variável Posição

a 1000

pt_a 1001

Page 17: Estrutura de dados II Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação

Ponteiros em Linguagem C

Onde usar isto???Funções!

Alocação Dinâmica

Não sei o tamanho que o vetor precisa ter….!

Não sei o tamanho que cada string precisa ter…

Não sei o tamanho que a matriz precisa ter…

Page 18: Estrutura de dados II Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação

Utilizando Ponteiros

void main() {int x = 10;int *pi;

pi = &x; /* *pi == 10 */(*pi)++; /* *pi == 11 */printf(“%d”, x);

}==> 11

ao alterar *pi estamos alterando o conteúdo de x

Page 19: Estrutura de dados II Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação

Utilizando Ponteiros

void main() {

int x = 10;

int *pi, *pj;

pi = &x; /* *pi == 10 */

pj = pi; /* *pj == 10 */

(*pi)++; /* (*pi, *pj, x) == 11 */

(*pj)++; /* (*pi, *pj, x) == 12 */

printf(“%d”, x); /* ==> 12 */ printf(“%x”, &pj); /* Endereco de x ==> 0x0c220c */

}

Page 20: Estrutura de dados II Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação

Ponteiros e Strings

Quando imprimimos uma cadeia de caracteres constantes (string) com printf o que é passado é o ponteiro para a cadeia.

Printf(“Ola como vai?”);

Dessa forma é possível carregar o endereço da string em um ponteiro do tipo char

char * lista;

lista = "Ola como vai ?";

printf("%s", lista );

Page 21: Estrutura de dados II Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação

Ponteiros e Strings

Na verdade, strings são arrays de caracteres e podem ser acessados através de char *

void main ()

{

char str[]=“abcdef”, *pc;

for (pc = str; *pc != ‘\0’; pc++)

putchar(*pc);

}

==> abcdef

o incremento de pc o posiciona sobre o próximo caracter (byte a byte)

Page 22: Estrutura de dados II Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação

Ponteiros e Strings

Outra forma de mostrar uma string usando laço

char *origem = "testando";

do{

printf("%c ", *origem);

}while (*origem++); /* origem == 0 encerra o laco */

Page 23: Estrutura de dados II Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação

Cuidados com Strings

É comum esquecer de alocar uma área para armazenamento de caracteres

void main() {

char *pc; char str[] = “Um string”;

strcpy(pc, str); /* erro! pc indeterminado */

...

}

Page 24: Estrutura de dados II Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação

Alocação dinâmica

Page 25: Estrutura de dados II Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação

Alocação dinâmica de memóriaAlocação dinâmica x alocação estática

Pode-se alocar dinâmicamente (em tempo de execução) um espaço de memória para uso com arrays, structs, etc...

int main() { int *p;

p = (int *) malloc(sizeof(int)); if (p == 0) { printf("ERRO: Sem memória\n"); return 1; } *p = 5; printf("&d\n", *p); free(p); return 0; }

Aloca de forma dinâmica espaço para um inteiro

Page 26: Estrutura de dados II Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação

Alocação dinâmica de memória

malloc

Utilizamos a função malloc() quando não conseguimos prever a quantidade de memória que nosso programa irá necessitar.

A função malloc() pode ser utilizada em run time para determinar o tamanho de um array.

Exemplochar * p; p = malloc(50);

free

Libera memória alocada previamente

Exemplo

free(p);

Page 27: Estrutura de dados II Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação

Alocação dinâmica de memória

void main() {

int numero = 10;

int *arranjo;

arranjo=(int *)malloc(numero * sizeof(int));

for (i=0; i < numero; i++) {

arranjo[i] = i;

}

free(arranjo);

}

Aloca de forma dinâmica espaço para um array de inteiros de 10 posições

Page 28: Estrutura de dados II Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação

#include <stdio.h> #include <stdlib.h> #include <conio.h>

int main() {

int *a; int i, k, m, min, temp, n;

/* Alocar memória para guardar o array */ printf("Quantos números quer ordenar? "); scanf("%d", &n); a = (int *) malloc( n * sizeof(int) );

if( a == NULL ) { printf("ERRO: nao ha memoria.\n"); exit(1); }

/* Receber os valores a ordenar */ for (i=0; i<n; i++) { printf("%d.º numero -> ",i+1); scanf("%d",&a[i]); }

/* Ordenar o array */ for( k=0; k<=n-1; k++ ) { /* descobre o índice do mínimo */ min = a[k]; m = k; for( i=k; i<=n-1; i++ ) if( a[i] < min ){ min = a[i]; m = i; }

/* troca a[k] com a[m] */ temp = a[k]; a[k] = a[m]; a[m] = temp; }

/* Escrever os elementos ordenados */ for( i=0; i<n; i++ ) printf("%d ", a[i]); printf("\n");

free( a ); /* libertar a memória */

getche();return 0;}

Page 29: Estrutura de dados II Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação

Estrutura de Dados Compostos

(Structs)

Page 30: Estrutura de dados II Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação

Definição

Uma estrutura (struct) ou registro em C é uma coleção de um ou mais valores, agrupados sob um único nome.

Estruturas constituem um recurso importante para organizar os dados utilizados por um programa graças à possibilidade de tratar um grupo de valores como uma única variável

Page 31: Estrutura de dados II Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação

Exemplo de uso

struct ponto { int x; int y;};

struct funcionario { int registro; char nome[30]; char depto[5]; float salario;};

Page 32: Estrutura de dados II Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação

Exemplo de uso

As declarações de ponto e funcionario, definem os respectivos tipos de dados, que podem ser utilizados em declarações de variáveis. Exemplos:

struct ponto p1, p2, p3; struct funcionario Joao;

Na primeira declaração, estão sendo declaradas as variáveis p1, p2 e p3 do tipo ponto. Na segunda declaração, é declarada a variável Joao do tipo funcionário.

Page 33: Estrutura de dados II Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação

Exemplo de uso

Para uma variável do tipo ponto, dizemos que x e y são seus campos ou membros. Os campos de uma variável podem ser acessados individualmente como variáveis usando-se o nome da variável seguido de "." e o nome do campo. Exemplos:

p1.x = 10;p1.y = 20;p2.x = p1.x + 5;p2.y = p2.y + 5;

Além disso, é possível atribuir a uma estrutura o valor de outra estrutura do mesmo tipo. Exemplos:

funcionario f = Joao;p3 = p2;

Page 34: Estrutura de dados II Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação

Estruturas complexas

Os campos de uma estrutura podem ser de qualquer tipo: tipos simples (int, char, float, etc), vetores, ou até mesmo estruturas. Exemplo:

struct retangulo { struct ponto pa; struct ponto pb;}

Page 35: Estrutura de dados II Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação

Uso de estruturas com funções

Uma vez que o tipo de uma estrutura foi declarado, é possível utilizá-lo em outras declarações (variáveis simples, vetores, funções, etc).

...struct ponto poligono[10];...

float dist(ponto p, ponto q) { int dx = p.x - q.x; int dy = p.y - q.y; return sqrt((double)dx*dx + (double)dy*dy);}

Page 36: Estrutura de dados II Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação

Passagem de estrutura por referência

Uma estrutura pode ser passada como parâmetro por referência numa função. Quando se usa uma referência (apontador), o acesso aos campos da mesma é feito através do operador "->" ao invés de ".". Exemplo:

void moveP(ponto* p, int dx, int dy){ p -> x += dx; p -> y += dy;}

...

moveP(&(r -> pa), dx, dy); moveP(&(r -> pb), dx, dy);

Page 37: Estrutura de dados II Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação

Retornando uma estrutura

Uma função pode ter uma estrutura como valor de retorno

struct ponto constroiPonto(int x, int y){ struct ponto temp; temp.x = x; temp.y = y; return temp;}

...struct ponto Origem = constroiPonto(0,0);

Page 38: Estrutura de dados II Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação

Declaração com valores iniciais

Ao declararmos uma estrutura, podemos também definir o seu valor inicial, de forma análoga a aquela utilizada para vetores. Exemplos:

struct ponto origem = {0,0};...struct ponto trapezio[] = { { 5,5}, {5, 10}, {10,5}, {10,13} };...

Page 39: Estrutura de dados II Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação

Usando ponteiros com structs

struct data{int dia;int mês; int ano;};

Definindo uma variável do tipo datastruct data dt;

Definindo um ponteiro para dtstruct data *pdt = &dt;

Fazendo referência a um elemento da estruturadt.dia ou (*pdt).dia ou pdt->diadt.mes ou (*pdt).mes ou pdt->mêsdt.ano ou (*pdt).ano ou pdt->ano

Page 40: Estrutura de dados II Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação

#include <stdio.h>typedef struct estrutura{ int valor; } ESTRUTURA;

void incrementa(ESTRUTURA * e){ printf(" Valor --> %i \n", e->valor); printf(" Valor --> %i \n", (*e).valor); /* outra forma de acessar */ (e->valor)++; /* incrementa valor */}

int main(){ ESTRUTURA d; /* declara variavel struct */ d.valor = 0; /* atribui valor inicial */ printf("Antes da funcao --> %d \n", d.valor); incrementa(&d); /* invoca a funcao */ printf("Apos a funcao --> %d\n", d.valor); return 0;

}

Exemplo de programa demonstrando uso de ponteiro, passagem de parâmetro

para função e estrutura

Page 41: Estrutura de dados II Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação

Alocação dinâmica de estruturas

É preciso armazenar esse endereço retornado pela malloc num ponteiro de tipo apropriado

Para alocar um tipo de dado que ocupa vários bytes, é preciso recorrer ao operador sizeof, que diz quantos bytes o tipo especificado tem

Vamos utilizar outra forma de declaração da struct:

struct tipo_data{

int dia, mes, ano;

};

typedef struct tipo_data DATA;

ATENÇÃO: data é o nome to tipo

Outra forma de declaração

typedef struct tipo_data{

int dia, mes, ano;

} DATA;

DATA *d;

d = malloc (sizeof (DATA));

d->dia = 31;

d->mes = 12;

d->ano = 2008;