A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

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

Apresentações semelhantes


Apresentação em tema: "Estrutura de dados II Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação."— Transcrição da apresentação:

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

2 Revisão Ponteiros, passagem de parâmetros para funções, alocação dinâmica e estruturas

3 Ponteiros

4 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ávelPosição a1000

5 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.

6 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

7 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

8 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 */

9 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

10 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 */ }

11 Outro exemplo ilustrado int i; int *p; p = &i; *p=5;

12 Relembrando... operador * declara-se com * int *x acessa-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)

13 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

14 Ponteiros ponteiros 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 */ }

15 Ponteiros espaço ocupado pelas variáveis Ponteiro aponta para o tamanho segundo seu tipo 1 byte (int *) 1 byte (float *) (char *)

16 Exemplo de uso Exemplo: int a = 1; int *pt_a; pt_a = &a; 1000 1001 1002 1003 1 1000 VariávelPosição a1000 pt_a1001

17 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…

18 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

19 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 */ }

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

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

22 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 */

23 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 */... }

24 Alocação dinâmica

25 Alocação dinâmica de memória Alocaçã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

26 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. Exemplo char * p; p = malloc(50); free Libera memória alocada previamente Exemplo free(p);

27 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

28 #include #include #include 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 ",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; }

29 Estrutura de Dados Compostos (Structs)

30 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

31 Exemplo de uso struct ponto { int x; int y; }; struct funcionario { int registro; char nome[30]; char depto[5]; float salario; };

32 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.

33 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;

34 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; }

35 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); }

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

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

38 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} };...

39 Usando ponteiros com structs struct data{ int dia; int mês; int ano; }; Definindo uma variável do tipo data struct data dt; Definindo um ponteiro para dt struct data *pdt = &dt; Fazendo referência a um elemento da estrutura dt.dia ou (*pdt).dia ou pdt->dia dt.mes ou (*pdt).mes ou pdt->mês dt.ano ou (*pdt).ano ou pdt->ano

40 #include 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

41 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;


Carregar ppt "Estrutura de dados II Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação."

Apresentações semelhantes


Anúncios Google