Ponteiros e Alocação Dinâmica

Embed Size (px)

Text of Ponteiros e Alocação Dinâmica

  • 1. Estrutura de Dados I UNICAPEduardo Arajo Oliveirahttp://eduoliveira.com Twitter: @oliveiraeduardo slide 1

2. PONTEIROSslide 2 3. Memria? slide 3 4. Uma memria umaseqncia de clulas de armazenamento(ou posies) slide 4 5. Uma varivel um aglomerado deuma ou mais clulas de memria. slide 5 6. VarivelAtributos de uma varivel nome: seqncia de caracteres utilizada para identificar avarivel; tipo: o tipo dos dados que sero armazenados na varivel; contedo: o valor armazenado na varivel; endereo: a localizao (posio) da varivel na memria;slide 6 7. slide 7 8. Varivel char sexo = M; Nome da varivel: sexo Tipo da varivel: char Contedo da varivel: M Endereo da varivel: 5slide 8 9. Varivel int idade = 31; Nome da varivel: idade Tipo da varivel: int Contedo da varivel: 31 Endereo da varivel: 1 slide 9 10. Varivel int idade = 31; Nome da varivel: idade Tipo da varivel: int Contedo da varivel: 31 Endereo da varivel: 1 slide 10 11. Variveis do tipo ponteiroPonteiros, como o prprio nome diz, um tipo de varivel queaponta para outra (de um tipo qualquer). Um ponteiro guarda o endereo de memria de uma varivel. Sintaxe: Variveis que so ponteiros so representadas daseguinte forma:tipo_dado_apontado *nome_variavel; int *ptr1; char *ptr2;slide 11 12. Variveis do tipo ponteiroUtilizado para: Substituir a manipulao de vetores/matrizes com eficincia; Passar valores e mudar valores dentro de funes; Manipular arquivos; Aumento de eficincia para algumas rotinas; Possibilitar a alocao dinmica de memria. slide 12 13. Variveis do tipo ponteiroOperadores de EndereoO& (endereo de) antes de um nome de varivel qualquerretorna o endereo desta varivel. O * (contedo de) antes de um nome de varivel do tipoponteiro retorna o contedo armazenadonaposiodememria apontada.Operaochamada deindireo oudesreferenciamento. slide 13 14. Variveis do tipo ponteirochar letra = Z;char *ptr = &letra; Nome da varivel: ptr Tipo da varivel: char * Contedo da varivel: 1 Endereo da varivel: 4 slide 14 15. Variveis do tipo ponteirovoid main(){int x = 50;int * ptr;printf (%i,x); /*exibe o contedo da varivel x (50)*/printf (%p,&x); /*exibe o endereo da varivel x*/ptr = &x; /*armazena em ptr o endereo de x*/printf (%p,ptr); /*exibe o contedo da varivel ptr*/printf (%p,&ptr); /*exibe o endereo da varivel ptr*/printf (%i,*ptr); /*exibe o contedo da varivel x*/} slide 15 16. Variveis do tipo ponteirovoid main () {int x;int *ptr;printf(Digite um valor para x:);scanf(%i, &x);ptr = &x;*ptr = *ptr + 1;printf(O valor de x %i, *ptr);printf(O endereo de x %i, ptr);} slide 16 17. Variveis do tipo ponteiro*p representa o contedo da varivel apontada. p representa o endereo de memria da varivel apontada. slide 17 18. Variveis do tipo ponteiroObservao Quando queremos indicar que um ponteiro est vazio, ouseja, no contm um endereo de uma varivel, atribumosa ele o valor NULL. NULL:Endereo de memria 0 (zero). Esta posio dememria no utilizada para armazenar dados. Exemplo:ptr = NULL; /* inicializa o ponteiro ptr*/ slide 18 19. Variveis do tipo ponteiroint a = 5, b = 7; (neste exemplo, um int ocupa 2bytes namemoria, e no 4, como em outros exemplos).int *ptr = NULL;ptr = &a; slide 19 20. Variveis do tipo ponteiroAtribuio Podemos atribuir o contedo de um ponteiro a outro. Dessaforma, teremos dois ponteiros referenciando o mesmo endereode memria. Exemplo:int a = 5, *p1, *p2;p1 = &a;p2 = p1;slide 20 21. Aritmtica de ponteirosSendo os ponteiros nmeros que representam posies dememria, podem ser realizadas algumas operaes aritmticassobre eles: Incremento; Decremento; Diferena; Comparao.slide 21 22. Aritmtica de ponteirosIncremento e Decremento Um ponteiro pode ser incrementado como qualquer outravarivel Se ptr um ponteiro para um determinado tipo, quando ptr incrementado, por exemplo, de uma unidade, o endereo quepassa a conter igual ao endereo anterior de ptr + sizeof(tipo)para que o ponteiro aponta A mesma situao ocorre para a operao de decremento,onde o endereo que passa a conter igual ao endereoanterior de ptr - sizeof(tipo) para que o ponteiro apontaslide 22 23. Aritmtica de ponteirosint main(int argc, char **argv) { int x = 5, *px = &x; double y = 5.0, *py = &y;printf("%i %in", x, px);printf("%i %in", x+1, px+1); 5 22935246 2293528printf("%f %in", y, py);5.000000 2293512printf("%f %in", y+1, py+1);6.000000 22935205 2293524printf("%i %in", x, px);printf("%i %in", x-1, px-1); 4 22935205.000000 2293512 printf("%f %in", y, py);4.000000 2293504 printf("%f %in", y-1, py-1); getchar();return 0;}slide 23 24. Aritmtica de ponteirosAlm das operaes de incremento e decremento, s possvelsomar ou subtrair inteiros de um ponteiro: ptr = ptr + 7; Esta expresso faz com que ptr aponte para o stimoelemento a partir do seu elemento atual. ptr = ptr 5; Esta expresso faz com que ptr aponte para o quintoelemento anterior ao elemento atual.Somar 2 a um ponteiro de inteiros de 4 bytes ir increment-lo em 8. Isso fazcom que o incremento de um ponteiro o posicione para o prximo elemento emum arranjo, o que geralmente o resultado intencionado. slide 24 25. Aritmtica de ponteiros Adio: somar um inteiro a um ponteiro Exemplo: float *p; p = p + 2; Fator de escala: o tamanho (nmero de bytes) do objeto apontado. Exemplo: fator de escala de uma varivel do tipo float: 4 p = p + 2 significa p = p + 2 * fator de escalaslide 25 26. Aritmtica de ponteiros Subtrao: subtrair um inteiro de um ponteiro Exemplo: float *p; p = p - 3; p = p - 3 significa p = p - 3 * fator de escala slide 26 27. Aritmtica de ponteiros Aritmtica de Ponteiros Incremento: somar um a um ponteiro Exemplo: float *p; p++; OU ++p;slide 27 28. Aritmtica de ponteiros Aritmtica de Ponteiros Decremento: subtrair um de um ponteiro Exemplo: float *p; p--; OU --p;slide 28 29. Aritmtica de ponteirosComparao possvel comparar dois ponteiros em uma expressorelacional.-Exemplo: possvel verificar se um ponteiro aponta para um endereomenor que o endereo apontado por outro ponteiro:if (px < py) printf(px aponta para memria mais baixa que py);slide 29 30. Aritmtica de ponteirosPrecedncia de Operadores O operador * e & tm maior precedncia que os operadoresaritmticos, de forma que:// obtm o valor do objeto apontador por px, adiciona 1 e//atribui o valor a yy = *px + 1;// y recebe o contedo do endereo de px+1y = *(px + 1);slide 30 31. Expresses com ponteirosPrecedncia de Operadores Os operadores ++ e -- possuem precedncia sobre o * eoperadores matemticos(*px)++; //soma 1 no contedo de px*px++; //adianta uma posio de memria e obtm o seu//contedo*(px--); //volta uma posio de memria e obtm//o seu contedo o mesmo que *px--Cuidado com ponteiros perdidos!slide 31 32. Aritmtica de ponteirosDiferena A operao de diferena entre elementos de mesmo tipopermite saber quantos elementos existem entre um endereo eoutro. Exemplo: #include void main(){int x = 5, *px = &x;int y = 10, *py = &y;printf("%i %dn", x, px);printf("%i %dn", y, py);printf("A diferenca entre eles eh: %d", py - px);getchar();slide 32 } 33. Ponteiro para estruturaComo os outros tipos do C, as estruturas podem serreferenciadas usando ponteiros.typedef struct { int numero; char nome[10]; float saldo;} conta;conta conta1;conta *ptr;ptr = &conta1; slide 33 34. Ponteiro para estruturaH duas formas para recuperar os valores de uma estruturausando o ponteiro: Se st uma estrutura e ptr um ponteiro para st, parareferenciar a estrutura usamos:(*ptr).elemento ou ptr->elementoslide 34 35. Ponteiro para estruturaconta conta1, *ptr; typedef struct {conta1.num_conta = 2;int num_conta;strcpy(conta1.nome, Maria);char nome[10];conta1.saldo = 482.25; float saldo;ptr = &conta1;} conta;printf(Numero = %in, (*ptr).num_conta);printf(Nome = %sn, (*ptr).nome);pritnf(Saldo = %fn, (*ptr).saldo);/* ou */printf(Numero = %in, ptr->num_conta);printf(Nome = %sn, ptr->nome);pritnf(Saldo = %fn, ptr->saldo);slide 35 36. Ponteiro para estruturatypdef struct{char titulo [40];float preco;} livro ;void main(){livro liv, *ptr;gets (liv.titulo);scanf(%f, &liv.preco);ptr = &liv;ptr->preco = ptr->preco * 0.1;printf(O preo de %s eh %f., pt->titulo, pt->preco);} slide 36 37. Ponteiro para estruturaExerccio Fazer um programa que permita a entrada de registros comnome, cidade e telefone de 1 pessoa usando a sintaxe deponteiro para estrutura. slide 37 38. Ponteiro e VetorO nome de um vetor corresponde ao endereo do seu primeiroelemento, isto , se v for um vetor ento v igual ao &v[0].Embora o nome de um vetor seja um ponteiro para o primeiroelemento do vetor, esse ponteiro no pode ser alterado durantea execuo do programa a que pertence.slide 38 39. Ponteiro e VetorExistem duas formas de colocar um ponteiro apontando para oprimeiro elemento de um vetor:int v[3] = {10, 20, 30};int * ptr;ptr = &v[0]; // ouptr = v;slide 39 40. Ponteiro e VetorAo contrrio de v, que um vetor (ponteiro constante associado sua prpria memria), ptr um ponteiro puro, e portantopode receber endereos de diferentes elementos de um vetor.int v[3] = {10, 20, 30};int *ptr;ptr = v;printf(%i %i, v[0], *ptr); /* 10 10 */ptr = &v[2]printf(%i %i, v[2], *ptr); /* 30 30 */slide 40 41. Ponteiro e VetorOutra sintaxe Colocamos em c o endereo do terceiro elemento de vetor:char vetor[5] = { a, e, i, o, u };char *c;c = &vetor[2]; Portanto:c[0] = i; c[1] = o e c[2] = u. Se tivssemos feito c = &vetor[3], ento:c[0] = o e c[1] = u. slide 41 42. Ponteiro e VetorUsando aritmtica de ponteiros, como acessar os valores dovetor usando a varivel ponteiro c ? #include void main(){int i;char vetor[5] = { a, e, i, o, u };char *c;c = vetor;for (i = 0; i < 5; i++) { printf("n%c ", c[i]); /* ou */ printf("%c ", *(c + i));}getchar(); } slide 42 43. Ponteiro e VetorUsando a sintaxe de ponteiro e de vetor de que formapoderemosacessar o caractere a p