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

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

Apontadores ou Ponteiros

Apresentações semelhantes


Apresentação em tema: "Apontadores ou Ponteiros"— Transcrição da apresentação:

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; bytes float y; 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 1 2 100 101 102 103 104 105 1 2 ‘A’ 100 101 102 103 104 105 Miguela Fernandes

4 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 x z ptr 1 2 ‘A’ 102 100 101 104 105 Miguela Fernandes

5 tipo_dado *nome_ponteiro;
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: 0x03062fd 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 1 0 Imprimir o conteúdo de uma variável
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 1 0 102 ptr 1 0 2 200 Miguela Fernandes

10 Manipular Ponteiros py=px; py fica a apontar p/ o mesmo que px
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 ‘A’ 1 2 100 101 102 103 104 105 106 107 108 109 110 111 112 100 102 107 140 141 142 143 144 145 146 147 148 149 150 151 152 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 *(ptr+n) == v[n] 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, }; 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, }; 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] = " "; 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. #include <stdio.h> #include <conio.h> void main() { int v[] = {4, 5, 8, 9, 8, 1, 0, 1, 9, 3}; int i = 0; while (v[i] != 0) ++i; printf("Nº de elementos antes de 0 %d\n",i); getch(); } /*exercício n 6*/ int *ptr; ptr=v; while ((*ptr) != 0) ++ptr; printf("Nº de elementos antes de 0 %d\n",ptr-v); 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 2 1 3 5 .. 100 102 104 106 108 110 112 114 …… 100 140 141 142 143 144 145 146 147 148 149 150 151 152 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”, *(ptr++)); printf(“%d”, *(ptr+2)); Miguela Fernandes

25 Aritmética de Ponteiros
vect 2 1 3 5 .. 100 102 104 106 108 110 112 114 …… 100 140 141 142 143 144 145 146 147 148 149 150 151 152 ptr printf(“%d”, ptr); //100 printf(“%d”, *ptr); // 2 printf(“%d”, ++ptr); printf(“%d”, vect [1]); printf(“%d”, (*ptr)++); printf(“%d”, *(ptr++)); printf(“%d”, *(ptr+2)); printf(“%d”, ptr); Miguela Fernandes

26 Aritmética de Ponteiros
vect 2 1 3 5 .. 100 102 104 106 108 110 112 114 …… 102 140 141 142 143 144 145 146 147 148 149 150 151 152 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 2 1 3 5 .. 100 102 104 106 108 110 112 114 …… 102 140 141 142 143 144 145 146 147 148 149 150 151 152 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 2 1 3 5 .. 100 102 104 106 108 110 112 114 …… 104 140 141 142 143 144 145 146 147 148 149 150 151 152 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 2 1 3 5 .. 100 102 104 106 108 110 112 114 …… 104 140 141 142 143 144 145 146 147 148 149 150 151 152 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); } ==> Miguela Fernandes

33 Exemplo - variação void main () { 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); } ==> Miguela Fernandes

34 Exemplo - variação 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++) printf(“ %d “, *pi++); } ==> 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: void main () { 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... void main () { 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: void main () { 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 * 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) 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] [0,0] [0,9] [1,9] [4,9] 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 static char 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 Array de Strings Comparando array de string com matriz de char
char *as[]= {“Joao”,“Maria”,“Antonio”,“Zacarias”,“Carlos”}; char ma[5][10]= Ponteiros (as) Matriz (ma) J o a o M a r i a A n t o n i o Z a c a r i a s C a r l o s \0 Miguela Fernandes

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

52 Ponteiros para Ponteiros
É possível definir ponteiros para ponteiros até um nível arbitrário de indirecção Ex: char *pc; /* ponteiro para char */ char **ppc;/* ponteiro para ponteiro para char */ pc = “teste”; ppc = &pc; putchar(**ppc); /* ==> ‘t’ */ Miguela Fernandes

53 Ponteiros para Ponteiros
Ponteiro para ponteiro para ponteiro... Ex: char *pc, **ppc, ***pppc; Um ponteiro permite modificar o objeto apontado ou apontar para outro objeto do mesmo tipo Miguela Fernandes


Carregar ppt "Apontadores ou Ponteiros"

Apresentações semelhantes


Anúncios Google