1 / 40

UDESC - SBS

UDESC - SBS. Departamento de Sistemas de Informação. LPG - I: Ponteiros e Vetores/Matrizes. Prof. Flavio Marcello Strelow flavio@sbs.udesc.br. Ponteiros.

Download Presentation

UDESC - SBS

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. UDESC - SBS Departamento de Sistemas de Informação LPG - I: Ponteiros e Vetores/Matrizes Prof. Flavio Marcello Strelow flavio@sbs.udesc.br Flavio M. Strelow

  2. Ponteiros • ponteiro é uma variável que contém o endereçode um dados, normalmente uma outra variável. Daí o nome, pois ele apontapara outra variável. • Ex: quando você anota o endereço de sua casa, você cria um ponteiro para ela. • declaração: "*" indica que a variável é um ponteiro • sintaxe: tipo_dado *nome_ponteiro; • Ex: int x; /*variável declarada como inteiro int *pi; /* compilador sabe que pi é ponteiro */ /* pi é um ponteiro para inteiro */ Flavio M. Strelow

  3. Ponteiros • espaço ocupado pelas variáveis 4 bytes 2 bytes 1 byte Flavio M. Strelow

  4. Ponteiros • o operador "&" quando aplicado sobre uma variável retorna o seu endereço • Ex: #include <stdio.h> void main (){ int x = 10, *pi; pi = &x; printf("&x: %p pi: %p", &x, pi); } R: => &x: 19BC pi: 19BC Obs.: Os valores apresentados são endereços de mémoria. Flavio M. Strelow

  5. Ponteiros • funcionamento de um ponteiro na memória • Ex: void main () { int var;int *ptr;var = 10;ptr = &var; } Flavio M. Strelow

  6. Ponteiros A Fig 1 dá uma noção gráfica do funcionamento de ponteiros. E está considerando que o endereçamento do sistema é dado por 2 bytes.Assim ptrocupará 2 bytes; var também 2 bytes, por ser uma variável int.O número 4052 da posição de memória do primeiro byte de var é apenas ilustrativo e, na prática, dependerá do local da memória onde o programa foi carregado. Mas supomos que seja este. Portanto, após a execução de ptr = &var;o conteúdo de ptr será 4052, ou seja, o primeiro byte da variável apontada.Com ptr apontando para var, podemos ler ou modificar o valor desta última de forma indireta através de ptr. Flavio M. Strelow

  7. Ponteiros • o operador "*" quando aplicado sobre um ponteiro em uma expressão aritmética retorna o dado apontado • Ex: void main () { int *tmp_ptr; int x, y; x = 10; tmp_ptr = &x; // tmp_ptra ponta para x y = *tmp_ptr; // conteúdo tmp_ptr = 10; portanto, y = 10. } Flavio M. Strelow

  8. Ponteiros • Ex.2: void main () { int x, *px; float y, *py; double largura, *altura; x=1; px = &x; /* px aponta para x */ *px = 0; /* conteúdo de px = 0 (x=0) */ x = *px + 1; /* x = conteúdo de px + 1 */ } Flavio M. Strelow

  9. Ponteiros • ponteiros são variáveis tipadas: possuem tipos diferentes para guardar endereços diferentes. Então um ponteiro para um tipo de dado int possui representação diferente de um ponteiro para tipo de dado float. (int *) ≠ (float *) ≠ (char *) • Ex: main() { int *ip, x; float *fp, z; ip = &x; /* OK */ fp = &z; /* OK */ ip = &z; /* erro */ fp = &x; /* erro */ } Flavio M. Strelow

  10. Utilizando Ponteiros • modificando valores de variáveis de forma indireta através de ponteiros. Ex: #include <stdio.h> void main() { int x = 10; int *pi; pi = &x; /* pi aponta para endereço de x  *pi == 10 */ (*pi)++; /* conteúdo de pi + 1  *pi == 11 */ printf("%d", x); } R: ==> 11 ao alterar *pi estamos alterando o conteúdo de x Flavio M. Strelow

  11. Utilizando Ponteiros Ex: #include <stdio.h> void main() { int x = 10; int *pi, *pj; pi = &x; /* *pi = 10 */ pj = pi; /* *pj = 10 */ (*pi)++; /* conteúdo de pi + 1(*pi, *pj, x) = 11 */ (*pj)++; /* conteúdo de pj + 1(*pi, *pj, x) = 12 */ printf("%d", x); /* ==> 12 */ } Flavio M. Strelow

  12. Exercício 1 • 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 Flavio M. Strelow

  13. Vetores e Ponteiros • ponteiros oferecem um eficiente e prático meio de acesso e manipulação dos elementos de uma array. • EX.: void main () { int ar[] = {10, 50, 20, 30}; int *ptr;ptr = &ar[0]; // ou ptr = ar; } Quando for executado, ptr estará associado ao primeiro byte da array conforme Fig 2. Flavio M. Strelow

  14. Vetores e Ponteiros • em float m[10]m é uma constante que endereça o primeiro elemento do vetor • portanto, não é possível mudar o valor de m • Ex: void main ( ) { float m[10], n[10]; float *pf; m = n; //erro: m é constante! pf = m; //ok } Flavio M. Strelow

  15. Referenciando Elementos • pode-se referenciar os elementos do vetor através do seu nome e o índice entre os colchetes: • Ex: #include <stdio.h> void main () { m[5] = 5.5; if (m[5] == 5.5) printf("Exito"); else printf("Falha"); } Flavio M. Strelow

  16. Referenciando Elementos • Pode-se referenciar os elementos de um vetor através de ponteiros: • Ex: #include <stdio.h> void main () { float m[] = { 1.0, 3.0, 5.75, 2.345 }; float *pf; pf = &m[2]; printf("%f", *pf); /* ==> 5.75 */ } Flavio M. Strelow

  17. Referenciando Elementos • Pode-se utilizar ponteiros e colchetes: • Ex.: #include <stdio.h> void main () { float m[] = { 1.0, 3.0, 5.75, 2.345 }; float *pf; pf = &m[2]; printf("%f", pf[0]); /* ==> 5.75 */ } • Note que o valor entre colchetes é o deslocamento a ser considerado a partir do endereço de referência: pf[n] => indica enésimo elemento a partir de pf Flavio M. Strelow

  18. Vetores - Aritmética de Ponteiros • É possível fazer operações aritméticas e relacionais entre ponteiros e inteiros • Soma: ao somar-se um inteiro n a um ponteiro, endereçamos n elementos a mais (n positivo) ou a menos (n negativo) pf[2] equivale a *(pf+2) *(pf + n) endereça n elementos a frente *(pf - n) endereça n elementos atrás pf++ endereça próximo elemento vetor pf-- endereça elemento anterior vetor Flavio M. Strelow

  19. Exemplo #include <stdio.h> void main () { int arint[] = { 1,2,3,4,5,6,7 }; int size = 7; /* tamanho do vetor */ int i, *pi; for (pi=arint, i=0; i < size; i++, pi++) printf(" %d ", *pi); } R: ==> 1 2 3 4 5 6 7 Flavio M. Strelow

  20. Exemplo - Variação #include <stdio.h> voidmain () { int arint[] = { 1,2,3,4,5,6,7 }; int size = 7; /* tamanho do vetor */ int i, *pi; for (pi=arint, i=0; i < size; i++) printf(" %d ", *pi++); } R: ==> 1 2 3 4 5 6 7 Flavio M. Strelow

  21. Exemplo - Variação #include <stdio.h> voidmain () { int arint[] = { 1,2,3,4,5,6,7 }; int size = 7; /* tamanho do vetor */ int i, *pi; pi = arint; printf(" %d ", *pi); pi += 2; printf(" %d ", *pi); pi += 2; printf(" %d ", *pi); pi += 2; printf(" %d ", *pi); } R: ==> 1 3 5 7 Flavio M. Strelow

  22. Operações Válidas Sobre Ponteiros • É valido: • somar ou subtrair um inteiro a um ponteiro (pi ± int) • incrementar ou decrementar ponteiros (pi++, pi--) • subtrair ponteiros (produz um inteiro) (pf - pi) • comparar ponteiros ( >, >=, <, <=, == ) • Não é válido: • somar ponteiros (pi + pf) • multiplicar ou dividir ponteiros (pi*pf, pi/pf) • operar ponteiros com double ou float (pi ± 2.0) Flavio M. Strelow

  23. Exercício 2 • Escreva um programa que imprima um vetor de inteiros na ordem inversa endereçando os elementos com um ponteiro Flavio M. Strelow

  24. Cuidados... • C não controla os limites dos vetores, o programador deve fazê-lo • Ex: encontre o erro!! #include <stdio.h> 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); } Flavio M. Strelow

  25. 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]); } Flavio M. Strelow

  26. Cuidados... • Um ponteiro deve sempre apontar para um local válido antes de ser utilizado • Ex: #include <stdio.h> voidmain () { int i=10, *pi; *pi = i;/*erro ! pi nao tem endereco valido*/ } Flavio M. Strelow

  27. Ponteiros Genéricos • Um ponteiro genérico é um ponteiro que pode apontar para qualquer tipo de dado • Define-se um ponteiro genérico utilizando-se o tipo void: #include <stdio.h> void main (){ void *pv; nt x=10; float f=3.5; pv = &x; /* aqui pv aponta para um inteiro */ pv = &f; /* aqui, para um float */ } Flavio M. Strelow

  28. Ponteiros Genéricos • O tipo de dado apontado por um void pointer deve ser controlado pelo usuário • Usando um type cast (conversão de tipo) o programa pode tratar adequadamente o ponteiro #include <stdio.h> void main (){ void *pv; pv = &x; printf("Inteiro: %d\n", *(int *)pv); /*=> 10*/ pv = &f; printf("Real: %f\n", *(float *)pv); /*=> 3.5*/ } type cast Flavio M. Strelow

  29. Ponteiros e Strings • strings são vetores de caracteres e podem ser acessados através de char * EX.: voidmain () { char str[]="abcdef", *pc; for (pc = str; *pc != ‘\0’; pc++) putchar(*pc); } R: ==> abcdef • o incremento de pco posiciona sobre o próximo caracter (byte a byte) Flavio M. Strelow

  30. Ponteiros e Strings • operações sobre strings com ponteiros • Ex.: void StrCpy (char *destino, char *origem) { // *origem==0 encerra while while (*origem) { *destino=*origem; origem++; destino++; } *destino='\0'; }// na condição do while (*origem) e (*origem != ‘\0’) são equivalentes origem a b c d e \0 a b destino Flavio M. Strelow

  31. Ponteiros e Strings • variação de strcpy: void strcpy (char *destino, char *origem) { while ((*destino = *origem) != ‘\0’) destino++, origem++; } *destino='\0'; Flavio M. Strelow

  32. Vetores Multidimensionais • vetores 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] Flavio M. Strelow

  33. Vetor de Caracteres • Percorrendo vetor com ponteiro: #include <stdio.h> #define L 5 #define C 10 void main () { char matriz[L][C]; char *pc; int i; for (i=0, pc=matriz[0]; i < (L * C) ; i++, pc++) *pc = 'P'; for (i=0, pc=matriz[0]; i < (L * C) ; i++, pc++) printf("%c", *pc); } Flavio M. Strelow

  34. Vetor de Caracteres • Percorrendo vetor com índices: #include <stdio.h> #define L 5 #define C 10 void main () { char matriz[L][C]; int i, j; for (i=0, j=0; i<L; i++) for (j=0; j<C; j++) matriz[i][j] = 'P'; for (i=0, j=0; i<L; i++) for (j=0; j<C; j++) printf("%c", matriz[i][j]); } //as colunas (dimensões mais a direita) mudam mais rápido Flavio M. Strelow

  35. Vetor de Strings • Neste caso, cada elemento do vetor é um ponteiro para um caracter • Declaração: char *arstr[] = {"Joao", "Maria", "Antonio", "Zacarias", "Carlos"}; • arstr é um vetor de ponteiros para char, iniciado com os strings indicados Flavio M. Strelow

  36. 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 Vetor de Strings • Comparando vetor de string com matriz de char char *as[]={"Joao","Maria","Antonio","Zacarias","Carlos"}; char ma[5][10]= {"Joao","Maria","Antonio","Zacarias","Carlos"}; Matriz (ma) Ponteiros (as) “Joao” “Maria” “Antonio” “Zacarias” “Carlos” Flavio M. Strelow

  37. Cuidados com Strings • É comum esquecer de alocar uma área para armazenamento de caracteres void main() { char *pc; char str[] = "Uma string"; strcpy(pc, str); /* erro! pc indeterminado */ ... } Flavio M. Strelow

  38. Ponteiros para Ponteiros • É possível definir ponteiros para ponteiros até um nível arbitrário de indireção • Ex: #include <stdio.h> void main () { char *pc; /* ponteiro para char */ char **ppc; /* ponteiro para ponteiro para char */ pc = "teste"; ppc = &pc; putchar(**ppc); /* ==> ‘t’ */ } Flavio M. Strelow

  39. Exemplo:Troca Variáveis - Ponteiros #include <stdio.h> void troca(int *, int *); int main(void){ int x, y; x = 3; y = 4; printf("main - x = %d, y=%d \n", x, y); troca(&x, &y); printf("main - x = %d, y=%d \n", x, y); } void troca(int *x, int *y){ int z; printf("troca - x = %d, y=%d \n", *x, *y); z = *x; *x = *y; *y = z; printf("troca - x = %d, y=%d \n", *x, *y); } Flavio M. Strelow

  40. Exercício 3 - Ponteiros Escreva uma função que receba três números reais (float) e reordene-os de forma decrescente. Teste sua implementação. Sugestão para protótipo da função: void ordena(float *a, float *b, float *c); Flavio M. Strelow

More Related