Aula 13 ponteiros - Programação 1

453 views

Published on

Aulas da Disciplina de Programação I do Professor Rodrigo Paes, UFAL

0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
453
On SlideShare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
23
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Aula 13 ponteiros - Programação 1

  1. 1. Programação I: Ponteiros Rodrigo Paes
  2. 2. Instituto de Computação – UFAL Exercício em sala  Objetivo: ler 03 numeros nas variaveis x,y e z e depois ordenar x,y e z de tal forma que x armazene o menor valor, y o intermediário e z o maior rodrigo@ic.ufal.br
  3. 3. Instituto de Computação – UFAL Código repetido  O que queremos com esses 03 trechos?  Trocar os valores de duas variáveis, correto?  Ou seja, queriamos isolar uma funcionalidade  Uma função de trocar valores rodrigo@ic.ufal.br
  4. 4. Instituto de Computação – UFAL Não seria melhor assim?  Ok … vamos tentar rodrigo@ic.ufal.br trocar(x,y) trocar(x,z) trocar(y,z)
  5. 5. Instituto de Computação – UFAL Tentativa 01  funcao_trocar_valores2.c rodrigo@ic.ufal.br
  6. 6. Instituto de Computação – UFAL Os valores foram trocados?  Não, né?  Passagem por valor  A passagem de parâmetro foi feita por valor  É feita uma cópia do valor da variável rodrigo@ic.ufal.br
  7. 7. Instituto de Computação – UFAL Passagem por valor rodrigo@ic.ufal.br
  8. 8. Instituto de Computação – UFAL Ponteiros  Ao declarar uma variável sempre informamos o tipo dela  int a;  float soma;  …  Lembra da 1a aula?  As variáveis ficam na memória  Endereço e Conteúdo rodrigo@ic.ufal.br
  9. 9. Instituto de Computação – UFAL Variáveis  Já sabemos alterar o conteúdo das variáveis  Comando de atribuição  resto = 25;  soma =soma + i;  …  Mas como descobrir o endereço de memória das nossas variáveis? rodrigo@ic.ufal.br En d. Conteúdo 1 34 2 “O rato roeu a roupa do rei de roma” 3 34.67 4 1 5 0 6 “aula de p1” 7 4677 … 123 n
  10. 10. Instituto de Computação – UFAL Operador &  Este operador nos fornece o endereço de memória de uma variável  Exemplo: main() { int a = 1; printf("O endereco de a eh: %pn",&a); } rodrigo@ic.ufal.br
  11. 11. Instituto de Computação – UFAL Um novo tipo de variável: ponteiro  O tipo da variável define os valores válidos para uma variável  Exemplo  int: valores inteiros  char: caracteres  float: ponto flutuante  …  Um ponteiro é um tipo de variável cujos valores válidos são endereços de memória rodrigo@ic.ufal.br
  12. 12. Instituto de Computação – UFAL Como funciona?  Imagine uma caixa postal  Caixa postal 22300  A caixa postal é só um endereço  Ela aponta para uma localização que contém um imóvel (conteúdo)  Os imóveis podem ser de vários tipos  Residencial casa, residencial apartamento, comercial …  Ou seja, a caixa postal contém um endereço para um conteúdo de um determinado tipo  A caixa postal é um ponteiro rodrigo@ic.ufal.br
  13. 13. Instituto de Computação – UFAL … voltando ao C  Um ponteiro é um endereço para um determinado tipo  int  float  char  outro ponteiro  … rodrigo@ic.ufal.br
  14. 14. Instituto de Computação – UFAL Ponteiros Endereço Identificador Conteúdo 0xFF4454 a 5 … … … … … … … … … … … … 0xBBA031 b 12 rodrigo@ic.ufal.br ponteiro_a
  15. 15. Instituto de Computação – UFAL Declaração de ponteiros main() { int a = 1; int b = 2; int *pt_a; … rodrigo@ic.ufal.br
  16. 16. Instituto de Computação – UFAL Atribuição com ponteiro main() { int a = 1; int b = 2; int *meu_ponteiro; meu_ponteiro = &a; // atribui o endereço de a … rodrigo@ic.ufal.br
  17. 17. Instituto de Computação – UFAL Acesso ao conteúdo do local apontado pelo ponteiro: *, o operador de “dereference” main() { int a = 1; int b = 2; int *pt_a; pt_a = &a; *pt_a = 50; // o que vai acontecer aqui? … rodrigo@ic.ufal.br
  18. 18. Instituto de Computação – UFAL Brincando com ponteiros  ponteiros.c rodrigo@ic.ufal.br
  19. 19. Instituto de Computação – UFAL Interessante né? mas e daí?  Vamos voltar para a nossa função de troca rodrigo@ic.ufal.br E se … •na nossa função recebessemos os endereços das variáveis que desejamos trocar •Com o endereço, poderíamos trocar os valores
  20. 20. Instituto de Computação – UFAL Ideia  trocar_valores(&x,&y) rodrigo@ic.ufal.br Endereço Identificador Conteúdo 0xFF4454 x 5 0xFF1242 y 3 0xBBA031 z 2 0xABA005 aux --- a b void trocar_valores(float *a, float *b) { float aux;
  21. 21. Instituto de Computação – UFAL Ideia  trocar_valores(&x,&y) rodrigo@ic.ufal.br Endereço Identificador Conteúdo 0xFF4454 x 5 0xFF1242 y 3 0xBBA031 z 2 0xABA005 aux 5 a b void trocar_valores(float *a, float *b) { float aux; aux = *a;
  22. 22. Instituto de Computação – UFAL Ideia  trocar_valores(&x,&y) rodrigo@ic.ufal.br Endereço Identificador Conteúdo 0xFF4454 x 5 0xFF1242 y 3 0xBBA031 z 2 0xABA005 aux 5 a b void trocar_valores(float *a, float *b) { float aux; aux = *a; *a = *b;
  23. 23. Instituto de Computação – UFAL Ideia  trocar_valores(&x,&y) rodrigo@ic.ufal.br Endereço Identificador Conteúdo 0xFF4454 x 3 0xFF1242 y 3 0xBBA031 z 2 0xABA005 aux 5 a b void trocar_valores(float *a, float *b) { float aux; aux = *a; *a = *b;
  24. 24. Instituto de Computação – UFAL Ideia  trocar_valores(&x,&y) rodrigo@ic.ufal.br Endereço Identificador Conteúdo 0xFF4454 x 3 0xFF1242 y 3 0xBBA031 z 2 0xABA005 aux 5 a b void trocar_valores(float *a, float *b) { float aux; aux = *a; *a = *b; *b = aux; }
  25. 25. Instituto de Computação – UFAL Ideia  trocar_valores(&x,&y) rodrigo@ic.ufal.br Endereço Identificador Conteúdo 0xFF4454 x 3 0xFF1242 y 5 0xBBA031 z 2 0xABA005 aux 5 a b void trocar_valores(float *a, float *b) { float aux; aux = *a; *a = *b; *b = aux; }
  26. 26. Instituto de Computação – UFAL Ideia  Ao sair … do escopo local as variáveis são eliminadas rodrigo@ic.ufal.br Endereço Identificador Conteúdo 0xFF4454 x 3 0xFF1242 y 5 0xBBA031 z 2if (y < z) // neste caso y é o menor { // troca os conteúdos de x e de y trocar_valores(&x,&y); } else // neste caso z é o menor
  27. 27. Instituto de Computação – UFAL O programa completo  funcao_trocar_valores3.c rodrigo@ic.ufal.br
  28. 28. Instituto de Computação – UFAL Passagem por referência  O que acabamos de fazer foi passar os parâmetros por referência ao invés de passar por valor  Passamos apenas uma referência para a variável externa  O seu valor não é copiado  Mais eficiente  Exige cuidados com efeitos colaterais rodrigo@ic.ufal.br
  29. 29. Instituto de Computação – UFAL Algumas reflexões  Pra que ponteiros?  C é de uma época em que os computadores eram menos poderosos  Necessidade de uso eficiente de processamento e memória  Logo, habilidade de trabalhar diretamente a memória é muito útil  E por que ainda usamos ponteiros?  Necessidade de eficiência ainda é importante rodrigo@ic.ufal.br
  30. 30. Instituto de Computação – UFAL Exemplos main() { int x = 7 ; int *px ; px = &x ; *px = 8 ; printf( "%dn" , x ) ; printf( "%dn" , &x ) ; printf( "%dn" , px ) ; printf( "%dn" , *px ) ; } rodrigo@ic.ufal.br
  31. 31. Instituto de Computação – UFAL Exemplos void exemplo2() { int firstvalue, secondvalue; int * mypointer; mypointer = &firstvalue; *mypointer = 10; mypointer = &secondvalue; *mypointer = 20; printf("%dn",firstvalue); printf("%dn",secondvalue); } rodrigo@ic.ufal.br
  32. 32. Instituto de Computação – UFAL Exemplos void exemplo3() { int firstvalue = 5, secondvalue = 15; int * p1, * p2; p1 = &firstvalue; p2 = &secondvalue; *p1 = 10; *p2 = *p1; p1 = p2; *p1 = 20; printf("%dn",firstvalue); printf("%dn",secondvalue); } rodrigo@ic.ufal.br
  33. 33. Instituto de Computação – UFAL Exemplos  Assuma que os seguintes endereços:  c é 1  d é 2  e é 3  Qual a saída do programa abaixo: char c = 'T', d = 'S'; char *p1 = &c; char *p2 = &d; char *p3; p3 = &d; printf("%cn",*p3); p3 = p1; printf("%c %pn", *p3, p3); *p1 = *p2; printf("%c %pn", *p1, p1 ); rodrigo@ic.ufal.br
  34. 34. Instituto de Computação – UFAL Exemplos int *p; int i; int k; i = 42; k = i; p = &i;  Qual dos seguintes comandos muda o valor de i para 75?  k = 75;  *k = 75;  p = 75;  *p = 75; rodrigo@ic.ufal.br
  35. 35. Instituto de Computação – UFAL Qual o valor de y? int main() { int y, *p, x; y = 0; p = &y; x = *p; x = 4; (*p)++; x; (*p) += x; printf ("y = %dn", y); return(0); } Rodrigo Paes – r0drigopaes@yahoo.com.br
  36. 36. Instituto de Computação – UFAL Exercício: escreva a função ordenar int main() { int a, b, c, d, e; printf("Digite 05 numerosn"); scanf("%d%d%d%d%d",&a,&b,&c,&d,&e); ordenar(&a,&b,&c,&d,&e); printf("Os numeros ordenados em ordem decrescente sao: %d, %d, %d, %d, %dn",a,b,c,d,e); return 0; } Rodrigo Paes – r0drigopaes@yahoo.com.br
  37. 37. Instituto de Computação – UFAL PONTEIROS E ARRAYS rodrigo@ic.ufal.br
  38. 38. Instituto de Computação – UFAL Lembra como você usa os arrays? … int array[9]; array[0] = 20; printf(“%d”, array[0] ); … rodrigo@ic.ufal.br
  39. 39. Instituto de Computação – UFAL Por debaixo dos panos  Uma variável array é um ponteiro constante para uma área de memória onde os elementos serão armazenados int array[9]; *array = 20; printf(“%d”, *array );  Perceba que a variável array é um ponteiro para o primeiro elemento rodrigo@ic.ufal.br 20 array
  40. 40. Instituto de Computação – UFAL E como acessar os outros elementos?  Aritmética de ponteiros int array[9]; *array = 20; *(array +1) = 30; *(array +2) = 40; rodrigo@ic.ufal.br 20 30 40 array 32 bits 32 bits 32 bits 32 bits 32 bits 32 bits 32 bits 32 bits 32 bits Desloca 1 * sizeof(int) bytes Desloca 2 * sizeof(int) bytes
  41. 41. Instituto de Computação – UFAL Então …  array[7]=96;  É idêntico a fazer:  *(array+7)=96;  Podemos também: int *p; int array[5]; p = array; p = &array[4]; p[-1] = 5; printf("%dn",array[3]); *(p-1) = 8; printf("%dn",array[3]); rodrigo@ic.ufal.br
  42. 42. Instituto de Computação – UFAL Atenção int *p; p[3] = 8; Certo ou errado? rodrigo@ic.ufal.br
  43. 43. Instituto de Computação – UFAL Quiz: pode ou não ? Qual a saída? #include <stdio.h> int main() { int a[10]; *a = 3; a[1]= 4; printf("%dn%dn",a[0],a[1]); } rodrigo@ic.ufal.br
  44. 44. Instituto de Computação – UFAL Quiz: pode ou não? Qual a saída? int main() { int a[10]; *a = 3; a[1]= 4; a++; *a =5; printf("%dn%dn",a[0],a[1]); } rodrigo@ic.ufal.br Não podemos alterar o ponteiro
  45. 45. Instituto de Computação – UFAL Passando arrays para funções void funcao(int *a, int tamanho) { int i; for (i=0; i< tamanho ; i++) { a[i] = i*i; } } main() { int x[5]; funcao(x,5); } rodrigo@ic.ufal.br
  46. 46. Instituto de Computação – UFAL Ponteiros para ponteiros char a; char * b; char ** c; a = 'z'; b = &a; c = &b; printf("%cn",a); printf("%cn",*b); printf("%cn",**c); rodrigo@ic.ufal.br
  47. 47. Instituto de Computação – UFAL Arrays bidimensionais :: estáticos int array1[2][2] = {{0, 1}, {2, 3}}; … Na memória: 0 1 2 3 O mesmo layout de: int array2[4] = { 0, 1, 2, 3 }; rodrigo@ic.ufal.br
  48. 48. Instituto de Computação – UFAL Arrays bidimensionais :: estáticos  Um array 2D não é a mesma coisa que int**  Array para ponteiros, só “funciona” automaticamente no primeiro nível  Logo:  int array1[2][2] = {{0, 1}, {2, 3}};  void function2(int a[][2]); ou:  void function2(int a[2][2]);  Diferente para alocação dinâmica rodrigo@ic.ufal.br
  49. 49. Instituto de Computação – UFAL Alocação dinâmica  Muitas vezes só sabemos o tamanho do nosso array durante a execução do programa  Usar esta abordagem permite protelar a decisão sobre o tamanho do bloco de memória necessário para armazenar um array  Quando aquela memória não é mais necessária, ela pode ser liberada para outros usos rodrigo@ic.ufal.br
  50. 50. Instituto de Computação – UFAL Alocação dinâmica  Exemplo. Alocação de um array com 10 inteiros int *iptr; iptr = (int *)malloc(10 * sizeof(int)); if (iptr == NULL) { ... Rotina de erro vem aqui ... } rodrigo@ic.ufal.br
  51. 51. Instituto de Computação – UFAL Alocação dinâmica e arrays int *iptr; iptr = (int *)malloc(10 * sizeof(int)); if (iptr == NULL) { ... Rotina de erro vem aqui ... } int k; for (k = 0; k < 10; k++) iptr[k] = 2; rodrigo@ic.ufal.br
  52. 52. Instituto de Computação – UFAL Alocar uma matriz de inteiros int **mi; int row,col; mi = malloc (ROWS * sizeof (int *)); for (row = 0; row < ROWS; row++) { mi[row] = malloc (COLS * sizeof (int)); } for (row = 0; row < ROWS; row++) { for (col = 0; col < COLS; col++) { mi[row][col] = 17; } } rodrigo@ic.ufal.br
  53. 53. Instituto de Computação – UFAL Alocar uma matriz de inteiros :: continuamente  https://dl.dropbox.com/u/17364381/p1/alocacao _continua_matriz.c rodrigo@ic.ufal.br
  54. 54. Instituto de Computação – UFAL Realocação https://dl.dropbox.com/u/17364381/p1/realloc.c rodrigo@ic.ufal.br
  55. 55. Instituto de Computação – UFAL Liberar a memória /* free example */ #include <stdlib.h> /* malloc, calloc, realloc, free */ int main () { int * buffer1, * buffer2, * buffer3; buffer1 = (int*) malloc (100*sizeof(int)); buffer2 = (int*) calloc (100,sizeof(int)); buffer3 = (int*) realloc (buffer2,500*sizeof(int)); free (buffer1); free (buffer3); return 0; } rodrigo@ic.ufal.br

×