1 / 53

Apontadores ou Ponteiros

Apontadores ou Ponteiros. T.L.P. 11º Ano. Conceitos básicos. Quando se define uma variável é guardado um espaço em memória do tamanho do tipo da variável int x; 2 bytes float y; 4 bytes char n[10]; 10 bytes.

diata
Download Presentation

Apontadores ou Ponteiros

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Apontadores ou Ponteiros T.L.P. 11º Ano

  2. Conceitos básicos • Quando se define uma variável é guardado um espaço em memória do tamanho do tipo da variável int x; 2 bytes float y; 4 bytes char n[10]; 10 bytes Miguela Fernandes

  3. Conceitos básicos • Exemplo int x= 10; • Não esquecer que ocupa 2 bytes. Então x está no endereço 102 • O operador de endereço como já é vosso conhecido é & • Então o endereço de x posso obtê-lo da seguinte forma: printf(“Endereço de x = %d ”, &x); // Endereço de x = 102 • Exemplo char z =‘A’ printf(“Endereço de z = %d ”, &z); // Endereço de x = 105 Miguela Fernandes

  4. x z ptr Apontadores/Ponteiros Os apontadores são variáveis que guardam os endereços de memória (&) de outras variáveis. Então podemos fazer ptr = &x // Estou a atribuir o endereço de x a ptr Miguela Fernandes

  5. Declarar Ponteiros • Sintaxe tipo_dado *nome_ponteiro; Exemplo: int x; int*ptr; /* compilador sabe que ptr é um ponteiro para inteiro */ *-O asterisco indica que é um ponteiro Exemplos char x, *p, y, * ap; //char * p ou char* p Float *p_num, num; Miguela Fernandes

  6. Operadores dos Ponteiros *desreferenciador Devolve o valor apontado pelo ponteiro. &referenciador Devolve o endereço de memória do seu operando. Precedência: Tanto o & como o * possuem precedência maior que qualquer outro operadore, com excepção do menos unário, que possui a mesma. Miguela Fernandes

  7. Iniciar Ponteiros • Já vimos que o operador “&” retorna endereço de uma variável • Para iniciar ponteiros temos que: int x = 10, *ptr; //Defino a var e o ponteiro ptr = &x; //Inicio o ponteiro printf(“&x: %x ptr: %x”, &x, ptr); &x: 0x03062fd8 ptr: 0x03062fd8 Miguela Fernandes

  8. Iniciar Ponteiros c/ NULL • Para iniciar ponteiros temos que: int x = 10, *ptr; //Defino a var e o ponteiro ptr = &x; //Inicio o ponteiro • Quando não pretendo iniciar logo o ponteiro com valores tenho de: ptr = NULL Miguela Fernandes

  9. Manipular Ponteiros x • Imprimir o conteúdo de uma variável int x = 10, *ptr = &x; printf(“ x = %d”, x); // x = 10 • Imprimir o conteúdo de um ponteiro printf(“ ptr = %d”,ptr); // x = 102 • Imprimir o valor para onde ele aponta printf(“ x = %d”, *ptr); // x = 10 ptr Miguela Fernandes

  10. Manipular Ponteiros Se py e px são pointers para inteiros, então podemos fazer a seguinte declaração: py=px; py fica a apontar p/ o mesmo que px void main(){ int x,*px,*py; x=9; px=&x; py=px; printf("x= %d\n",x); printf("&x= %d\n",&x); printf("px= %d\n",px); printf("*px= %d\n",*px); printf("*py= %d\n",*py); } Miguela Fernandes

  11. Exercício 1 1- Declara uma variável para guardar a tua idade e inicial um ponteiro para a variável idade. 2- O que estou a fazer com seguinte declaração: int* x, y, z; 3- Fazer um programa que veja os endereços de memória de uma variável do tipo inteiro, char e float. Pretende-se que o faças 1º sem recorrer a ponteiros e depois com recurso a estes. Miguela Fernandes

  12. Cuidado com os tipos de dados • Os ponteiros são variáveis tipadas: (int *) ≠ (float *) ≠ (char *) void main() { int *p1, x; float *p2, y; p1 = &x; /* OK */ p2 = &y; /* OK */ p1 = &z; /* Erro */ p2 = &x; /* Erro */ } Um apontador para o tipo xpty, avança sempre o sizeof(xpty) Miguela Fernandes

  13. Cuidado com os tipos de dados c i f ptr_c ptr_i ptr_f Sizeof(char) ≠ Sizeof(int) ≠ Sizeof(float) Não posso fazer: ptr_c = &i; ptr_i=&f; Miguela Fernandes

  14. Exercício 2 • Pratique a declaração e utilização de ponteiros. • defina e inicialize uma variável inteira • defina um ponteiro para inteiro • modifique o valor da variável através do ponteiro • verifique os novos valores da variável usando printf Miguela Fernandes

  15. Ponteiros Genéricos • Um ponteiro genérico é um ponteiro que pode apontar para qualquer tipo de dado • Define-se um ponteiro genérico utilizando o tipo void: void *ptr; int x=10; float y=88.2; ptr = &x; /* neste caso ptr aponta para um inteiro */ ptr = &f; /* agora para um float */ Miguela Fernandes

  16. Ponteiros Genéricos O tipo de dado apontado por um void pointer deve ser controlado pelo utilizador através do cast Sintaxe: * (tipo *) ponteiro ptr = &x; printf(“Inteiro: %d\n”, *(int *) ptr ); /* Inteiro = 10*/ ptr = &f; printf(“Float: %4.2f\n”, *(float *) ptr ); /*Float = 88.20*/11 Miguela Fernandes

  17. Ponteiros e Vectores Relembrar: O nome de um vector é um ponteiro (constante) para o 1º elemento do vector Exemplo: int v[10]; v == &v[0] Int *ptr; ptr= &v[0] // ou ptr =v; Então: *(ptr+1) é igual a v[1], *(ptr+2) é igual a v[2], *(ptr+n) == v[n] Miguela Fernandes

  18. Ponteiros e Vectores Não esquecer: • float x[20]x é um apontador constante que endereça o primeiro elemento do vector, como tal, não é possível mudar o seu valor. Exemplo: float x[10], y[10]; float *ptr_f; x = y; /* NUNCA ERRO: x é constante ! */ ptr_f = x; /* SEMPRE OK */ Miguela Fernandes

  19. Ponteiros e Vectores • Pode referenciar-se os elementos de um vector através de ponteiros: float x[] = { 11.0, 2.0, 5.4, 7.987 }; float *ptr_f; ptr_f= &x[1]; printf(“%f”, *ptr_f); /* 2.0 */ printf(“%f”, *(ptr_f +1)); /* 5.4 */ Miguela Fernandes

  20. Ponteiros e Vectores Pode utilizar-se ponteiros e parênteses rectos: float x[] = { 11.0, 2.0, 5.4, 7.987 }; float *ptr_f; ptr_f = &x[1]; printf(“%f”, ptr_f[0]); /* ==> 2.0 */ Nota O valor entre chavetas é o deslocamento a ser considerado a partir do endereço de referência ptr_f[n] => indica enésimo elemento a partir de Miguela Fernandes

  21. Ponteiros e Vectores Exemplo 1 /*exercicio ptr_5*/ #include <stdio.h> #include <conio.h> #define TAM 10 char v[TAM] = "0123456789"; void main() { clrscr(); int i; for (i = 0; i < TAM; ++i) { printf("&v[i]=%p (v+i)=%p v[i]=%c\n", &v[i], (v+i), v[i]); } getch(); } Miguela Fernandes

  22. Ponteiros e Vectores Exemplo 2 Programa que dá o numero de elementos de um vector antes de encontrar o 0. Miguela Fernandes

  23. Aritmética de Ponteiros • É possível fazer operações aritméticas e relacionais entre ponteiros e inteiros • Soma ou subtracção int x[10], *ptr; ptr[2] equivale a *(ptr+2) *(ptr + n) acede ao conteúdo de n elementos a frente *(ptr - n) acede ao conteúdo de n elementos atrás ptr++ acede ao próximo endereço elemento vector * ptr-- acede ao endereço anterior do vector * * Não esquecer que avança o tamanho do tipo int 2 bytes, float 4 bytes, etc. Miguela Fernandes

  24. Aritmética de Ponteiros vect ptr Quais os seguintes resultados: ptr_10 printf(“%d”, ptr); printf(“%d”, *ptr); printf(“%d”, ++ptr); // Porque não printf(“%d”, ptr++); ??? printf(“%d”, vect [1]); printf(“%d”, (*ptr)++); printf(“%d”, vect [1]); printf(“%d”, *(ptr++)); printf(“%d”, *(ptr+2)); printf(“%d”, ptr); Miguela Fernandes

  25. Aritmética de Ponteiros vect ptr printf(“%d”, ptr);//100 printf(“%d”, *ptr); // 2 printf(“%d”, ++ptr); printf(“%d”, vect [1]); printf(“%d”, (*ptr)++); printf(“%d”, vect [1]); printf(“%d”, *(ptr++)); printf(“%d”, *(ptr+2)); printf(“%d”, ptr); Miguela Fernandes

  26. Aritmética de Ponteiros vect ptr printf(“%d”, ptr);//100 printf(“%d”, *ptr); // 2 printf(“%d”, ++ptr);// 2 printf(“%d”, vect [1]); // 0 printf(“%d”, (*ptr)++); // 0 printf(“%d”, vect [1]); printf(“%d”, *(ptr++)); printf(“%d”, *(ptr+2)); printf(“%d”, ptr); Miguela Fernandes

  27. Aritmética de Ponteiros vect ptr printf(“%d”, ptr);//100 printf(“%d”, *ptr); // 2 printf(“%d”, ++ptr);// 2 printf(“%d”, vect [1]); // 0 printf(“%d”, (*ptr)++); // 0 printf(“%d”, vect [1]); // 1 printf(“%d”, *(ptr++)); printf(“%d”, *(ptr+2)); printf(“%d”, ptr); Miguela Fernandes

  28. Aritmética de Ponteiros vect ptr printf(“%d”, ptr);//100 printf(“%d”, *ptr); // 2 printf(“%d”, ++ptr);// 2 printf(“%d”, vect [1]); // 0 printf(“%d”, (*ptr)++); // 0 printf(“%d”, vect [1]); // 1 printf(“%d”, *(ptr++)); // 1 printf(“%d”, *(ptr+2)); printf(“%d”, ptr); Miguela Fernandes

  29. Aritmética de Ponteiros vect ptr printf(“%d”, ptr);//100 printf(“%d”, *ptr); // 2 printf(“%d”, ++ptr);// 2 printf(“%d”, vect [1]); // 0 printf(“%d”, (*ptr)++); // 0 printf(“%d”, vect [1]); // 1 printf(“%d”, *(ptr++)); // 1 printf(“%d”, *(ptr+2)); // 5 printf(“%d”, ptr); // 104 Miguela Fernandes

  30. 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 */ } Miguela Fernandes

  31. Utilizando Ponteiros void main() { int x = 10; int *pi; pi = &x; /* *pi == 10 */ (*pi)++; /* *pi == 11 */ printf(“%d”, x); } ==> 11 Ao alterar *pi estamos a alterar o conteúdo de x Miguela Fernandes

  32. Exemplo void main () { int arint[] = { 1,2,3,4,5,6,7 }; int size = 7; /* tamanho do array */ int i, *pi; for (pi=arint, i=0; i < size; i++, pi++) printf(“ %d “, *pi); } ==> 1 2 3 4 5 6 7 Miguela Fernandes

  33. Exemplo - variação voidmain () { int arint[] = { 1,2,3,4,5,6,7 }; int size = 7; /* tamanho do array */ int i, *pi; pi = arint; printf(“ %d “, *pi); pi += 2; printf(“ %d “, *pi); pi += 2; printf(“ %d “, *pi); pi += 2; printf(“ %d “, *pi); } ==> 1 3 5 7 Miguela Fernandes

  34. Exemplo - variação voidmain () { int arint[] = { 1,2,3,4,5,6,7 }; int size = 7; /* tamanho do array */ int i, *pi; for (pi=arint, i=0; i < size; i++) printf(“ %d “, *pi++); } ==> 1 2 3 4 5 6 7 Miguela Fernandes

  35. Operações Válidas Sobre Ponteiros • Podemos: • somar ou subtrair um inteiro a um ponteiro (ptr ± int) • incrementar ou decrementar ponteiros (ptr++, ptr--) • subtrair ponteiros (produz um inteiro) (ptr1 – ptr2) • comparar ponteiros ( >, >=, <, <=, == ) • Não podemos: • somar ponteiros (ptr1 + ptr2) • multiplicar ou dividir ponteiros (ptr1*ptr2, ptr1/ptr2) • usar ponteiros com double ou float (pi ± 2.0) Miguela Fernandes

  36. Exercício 3 • Escreva um programa que imprima um vector de inteiros na ordem inversa endereçando os elementos com um ponteiro Miguela Fernandes

  37. Cuidados... • C não controla os limites dos arrays, o programador deve fazê-lo • Ex: • encontrar o erro: voidmain () { int arint[] = { 1,2,3,4,5,6,7 }; int size = 7, i, *pi; for (pi=arint, i=0; i < size; i++, pi += 2) printf(“ %d “, *pi); } Miguela Fernandes

  38. Cuidados... voidmain () { int arint[] = { 1,2,3,4,5,6,7 }; int size = 10; int i; for (pi=arint, i=0; i < size; i++) printf(“ %d “, arint[i]); } Miguela Fernandes

  39. Cuidados... • Um ponteiro deve sempre apontar para um local válido antes de ser utilizado • Ex: voidmain () { int i=10, *pi; *pi = i; /*erro ! pi nao tem endereco valido*/ } Miguela Fernandes

  40. Ponteiros e Strings • strings são vectores de caracteres e podem ser acedidos através de char * voidmain () { 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) Miguela Fernandes

  41. Ponteiros e Strings • operações sobre strings com ponteiros void StrCpy (char *destino, char *origem) { while (*origem) /* *origem==0 encerra while */ { *destino=*origem; origem++; destino++; } *destino='\0'; } origem a b c d e \0 a b destino Miguela Fernandes

  42. Ponteiros e Strings • variação de strcpy: void strcpy (char *destino, char *origem) { while ((*destino = *origem) != ‘\0’) destino++, origem++; } Miguela Fernandes

  43. Arrays Multidimensionais • Arrays podem ter diversas dimensões, cada uma identificada por um par de colchetes na declaração • Ex: char matriz[5][10]; • declara uma matriz de 5 linhas e 10 colunas: • na memória, entretanto, os caracteres são armazenados linearmente: [0,0] [4,9] [4,9] [1,9] [0,9] [0,0] Miguela Fernandes

  44. Array de Caracteres • Percorrendo array com ponteiro: void main () { char matriz[5][10]; char *pc; int i; for (i=0, pc=matriz[0]; i < 50; i++, pc++) *pc = ‘ ‘; } Miguela Fernandes

  45. Array de Caracteres • Percorrendo array com indices: void main () { char matriz[5][10]; int i, j; for (i=0, j=0; i<5; i++) for (; j<10; j++) matriz[i][j] = ‘ ‘; } • as colunas (dimensões mais a direita) mudam mais rápido Miguela Fernandes

  46. Array de Inteiros • Exemplo: considere o problema de conversão de data dia_do_ano: um dos 365 dias do ano, convertido a partir do mes e dia do mes • Tabela que indica dias dos meses incluindo bissexto staticchar tabela_dias[2][13] = { { 0,31,28,31,30,31,30,31,31,30,31,30,31 } { 0,31,29,31,30,31,30,31,31,30,31,30,31 } }; Miguela Fernandes

  47. Conversão de Data • Organização lógica e física da tabela: Miguela Fernandes

  48. Conversão de Data • /* dia_do_ano: calcula dia do ano a partir do dia do mes */ int dia_do_ano(int ano, int mes, int dia) { int i, bis; bis = (ano%4)==0 && (ano%100)!=0 || (ano%400)==0; for (i = 1; i < mes; i++) dia += tabela_dias[bis][i]; return dia; } Miguela Fernandes

  49. Array de Strings • Neste caso, cada elemento do array é um ponteiro para um caracter • Declaração: char *arstr[] = {“Joao”, “Maria”, “Antonio”, “Zacarias”, “Carlos”}; • arstr é um array de ponteiros para char, iniciado com os strings indicados Miguela Fernandes

  50. J o a o \0 M a r i a \0 A n t o n i o \0 Z a c a r i a s \0 C a r l o s \0 Array de Strings • Comparando array de string com matriz de char char *as[]= {“Joao”,“Maria”,“Antonio”,“Zacarias”,“Carlos”}; char ma[5][10]= {“Joao”,“Maria”,“Antonio”,“Zacarias”,“Carlos”}; Ponteiros(as) Matriz (ma) Miguela Fernandes

More Related