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

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

Apontadores ou Ponteiros T.L.P. 11º Ano. Miguela Fernandes 2 Conceitos básicos Quando se define uma variável é guardado um espaço em memória do tamanho.

Apresentações semelhantes


Apresentação em tema: "Apontadores ou Ponteiros T.L.P. 11º Ano. Miguela Fernandes 2 Conceitos básicos Quando se define uma variável é guardado um espaço em memória do tamanho."— Transcrição da apresentação:

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

2 Miguela Fernandes 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

3 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 Não esquecer que ocupa 2 bytes. Então x está no endereço 102 O operador de endereço como já é vosso conhecido é & 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 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 = A

4 Miguela Fernandes 4 Apontadores/Ponteiros x z ptr 1 2A 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

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

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

7 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

8 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

9 Miguela Fernandes 9 Manipular Ponteiros 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 = x 200 ptr

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

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

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

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

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

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

16 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 = */11

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

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

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

20 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

21 Miguela Fernandes 21 Ponteiros e Vectores Exemplo 1 /*exercicio ptr_5*/ #include #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(); }

22 Miguela Fernandes 22 Ponteiros e Vectores Exemplo 2 #include 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*/ #include void main() { int v[] = {4, 5, 8, 9, 8, 1, 0, 1, 9, 3}; int *ptr; ptr=v; while ((*ptr) != 0) ++ptr; printf("Nº de elementos antes de 0 %d\n",ptr-v); getch(); } Programa que dá o numero de elementos de um vector antes de encontrar o 0.

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

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

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

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

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

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

29 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

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

31 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

32 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); } ==>

33 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); } ==>

34 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++); } ==>

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

36 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

37 Miguela Fernandes 37 Cuidados... C não controla os limites dos arrays, o programador deve fazê-lo Ex: encontrar o erro: 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); }

38 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]); }

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

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

41 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'; } a b cd e \0 ab origem destino

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

43 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,9] [1,9] [0,0] [4,9]

44 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 = ; }

45 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

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

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

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

49 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

50 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]= {Joao,Maria,Antonio,Zacarias,Carlos}; Ponteiros (as) 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 Matriz (ma)

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

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

53 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


Carregar ppt "Apontadores ou Ponteiros T.L.P. 11º Ano. Miguela Fernandes 2 Conceitos básicos Quando se define uma variável é guardado um espaço em memória do tamanho."

Apresentações semelhantes


Anúncios Google