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

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

Prof. Ricardo Santos PONTEIROS.

Apresentações semelhantes


Apresentação em tema: "Prof. Ricardo Santos PONTEIROS."— Transcrição da apresentação:

1 Prof. Ricardo Santos PONTEIROS

2 Ponteiros Um ponteiro é uma variável que contém um endereço de memória. Este endereço é a posição de outra variável na memória. Se uma variável contém o endereço de uma outra, dizemos que a primeira aponta para a segunda. Declaração: tipo_base *nome; Exemplo: int *p; Onde tipo_base é qualquer tipo válido em C e nome é o nome da variável ponteiro. O tipo_base define que tipo de variáveis o ponteiro pode apontar.

3 Ponteiros Uma variável ponteiro ocupa duas partes na memória, chamadas de parte de posição e parte de valor. int *p;(1) *p = 10;(2) Memória null p Memória p 10 Parte de Posição Parte de Valor Parte de Posição Efeito da instrução 1 Efeito da instrução 2

4 Ponteiros Na instrução 1 a variável p só tem parte de posição e seu conteúdo é null pois ainda não aponta para nenhum endereço. Na instrução 2 é que p terá a parte de valor e a parte de posição terá um endereço (diferente de null). int *p;(1) *p = 10;(2) Memória null p Memória p 10 Parte de Posição Parte de Valor Parte de Posição Efeito da instrução 1 Efeito da instrução 2

5 Operadores de Ponteiros Para selecionar cada uma das partes de uma variável ponteiro p, usa-se: p para especificar a parte de posição da variável p. Pode conter um endereço de memória ou null se não estiver apontado para um valor. * p para especificar a parte de valor da variável p. Observação: O operador & serve para especificar o endereço na memória da variável que o segue.

6 Exemplificando Suponha que a variável contador usa a posição de memória 2000 para armazenar seu valor. Também assuma que contador tem o valor 100. int *m;// m e um ponteiro para o tipo int m = &contador; // m recebe o endereço de contador q = *m// q recebe o valor que está no // endereço de m 1a. instrucao: A variável m não é do tipo, mas aponta para um valor do tipo int. Após a 2a. instrução m terá o valor Após a 3a. instrução q terá o valor 100.

7 Quais as Saídas Produzidas I? int destino=0, fonte=0, *m; fonte = 10; m = &fonte; destino = *m; printf(“%d”, destino);

8 int destino=0, fonte=0, *m; Quais as Saídas Produzidas I? int destino=0, fonte=0, *m; fonte = 10; m = &fonte; destino = *m; printf(“%d”, destino); fonte destino m 0 0 NULL

9 fonte = 10; Quais as Saídas Produzidas I? int destino=0, fonte=0, *m; fonte = 10; m = &fonte; destino = *m; printf(“%d”, destino); m NULL destino 0 fonte 10

10 m = &fonte; Quais as Saídas Produzidas I? int destino=0, fonte, *m; fonte = 10; m = &fonte; destino = *m; printf(“%d”, destino); m destino 0 fonte 10

11 destino = *m; Quais as Saídas Produzidas I? int destino=0, fonte, *m; fonte = 10; m = &fonte; destino = *m; printf(“%d”, destino); m destino 10 fonte 10

12 printf(“%d”, destino); Quais as Saídas Produzidas I? int destino=0, fonte, *m; fonte = 10; m = &fonte; destino = *m; printf(“%d”, destino); m destino 10 fonte 10

13 Quais as Saídas Produzidas II? int x, *p1, *p2; x = 10; p1 = &x; p2 = p1; printf("%d", *p2)

14 int x=10, *p1, *p2; Quais as Saídas Produzidas II? int x=10, *p1, *p2; p1 = &x; p2 = p1; printf("%d", *p2) x p2 p1 10 NULL

15 p1 = &x; Quais as Saídas Produzidas II? int x=10, *p1, *p2; p1 = &x; p2 = p1; printf("%d", *p2) x p2 p1 10 NULL

16 p2 = p1; Quais as Saídas Produzidas II? int x=10, *p1, *p2; p1 = &x; p2 = p1; printf("%d", *p2) x p2 p1 10

17 printf("%d", *p2) Quais as Saídas Produzidas II? int x=10, *p1, *p2; p1 = &x; p2 = p1; printf("%d", *p2) x p2 p1 10

18 int a=1, b=2, *pa, *pb; Quais as Saídas Produzidas III? int a=1, b=2, *pa, *pb; printf("a=%d b=%d\n",a,b); pa=&a; pb=&b; *pa+=5; *pb+=5; printf("a=%d b=%d\n",a,b); a pb pa 1 NULL b 2

19 printf("a=%d b=%d\n",a,b); Quais as Saídas Produzidas III? int a=1, b=2, *pa, *pb; printf("a=%d b=%d\n",a,b); pa=&a; pb=&b; *pa+=5; *pb+=5; printf("a=%d b=%d\n",a,b); a pb pa 1 NULL b 2

21 *pa+=5; *pb+=5; Quais as Saídas Produzidas III? int a=1, b=2, *pa, *pb; printf("a=%d b=%d\n",a,b); pa=&a; pb=&b; *pa+=5; *pb+=5; printf("a=%d b=%d\n",a,b); a pb pa 6 b 7

22 printf("a=%d b=%d\n",a,b); Quais as Saídas Produzidas III? int a=1, b=2, *pa, *pb; printf("a=%d b=%d\n",a,b); pa=&a; pb=&b; *pa+=5; *pb+=5; printf("a=%d b=%d\n",a,b); a pb pa 6 b 7

24 Cuidado ao Manipular Ponteiros Onde está o erro no código abaixo? int x, *p; x = 10; *p = x; O problema do código acima é que estamos atribuindo o conteúdo da variável x para alguma posição da memória desconhecida. Desconhecida porque p não tem parte de valor, só parte de posição (que é null), ou seja, p foi declarada mas nunca apontou para um endereço. O certo seria: int x, *p; x = 10; p = &x// p = (int) malloc(sizeof(int)); // *p = x;

25 Aritmética de Ponteiros Existem apenas duas operações aritméticas que podem ser utilizadas com ponteiros: adição e subtração. Cada vez que um ponteiro é incrementado, ele aponta para a posição de memória do próximo elemento de seu tipo base. O mesmo raciocínio quando decrementado. Vamos analisar as instruções I, II e III: I. Vamos imaginar que p passe a apontar para o endereço II. Partindo do princípio que cada elemento do tipo int ocupa 2 bytes, o próximo elemento do tipo int está na posição 2002, então p passa a conter 2002 e não III. Estando p apontando para a posição 2002, ao incremetar 10, p passa a conter a = 100; int *p; p=&a; (I) p++; (II) p=p+10; (III)

26 Aritmética de Ponteiros (I)a = 100; int *p; p=&a; (II)p++; (III)p=p+10;

27 Comparação de Ponteiros Qual a saída produzida? main(){ int a,b,*p,*q; a=10; b=10; p=&a; q=&b; if (p==q) { printf("Valores iguais.\n"); }else{ printf("valores diferentes.\n"); } getch(); }

28 printf("valores diferentes.\n"); Comparação de Ponteiros Qual a saída produzida? main(){ int a,b,*p,*q; a=10; b=10; p=&a; q=&b; if (p==q) { printf("Valores iguais.\n"); }else{ printf("valores diferentes.\n"); } getch(); } Porque?

29 Ponteiros e Vetores Em C, o nome de um vetor sem índice retorna o endereço inicial do vetor, que é o primeiro elemento. No trecho de código abaixo, p recebe o endereço do 1o. elemento da vetor frase. char frase[80], *p; p = frase;

30 Diferentes Formas de Acessar Um Vetor C fornece dois métodos para acessar os elementos de um vetor: Indexação e Aritmética de ponteiros. Para acessarmos o 5o. elemento da vetor frase do exemplo anterior usamos uma das formas abaixo: char frase[80], *p; p = frase; frase[4](1) *(p+4)(2) *(frase + 4)(3) p[4](4) As linhas 1 e 4 utilizam indexação para acessar o vetor e as linhas 2 e 3 utilizam aritmética de ponteiros.

31 Diferentes Formas de Acessar Um Vetor main(){ int vet[]={10, 20, 30,40,50}; /* Se o nome do vetor sozinho é um ponteiro para o 1o. elemento, então *(vet) fazreferência ao conteúdo deste endereço. */ for (int i=0; i < 5; i++){ printf("%d\n",*(vet+i)); } getch(); }

32 Diferentes Formas de Acessar Um Vetor int *p=vet; for (int i=0; i < 5; i++){ printf("%d\n",*(p+i)); // ou printf("%d\n",*(vet+i)); } /* forma tradicional de se referenciar a um vetor. */ for (int i=0; i < 5; i++){ printf("%d\n",vet[i]); } /* Em C qualquer ponteiro pode ser indexado como se fosse um vetor. */ for (int i=0; i < 5; i++){ printf("%d\n",p[i]); }

33 Vetor de Ponteiros Ponteiros podem ser organizados em vetores como qualquer outro tipo de dado. A declaração de um vetor de 10 ponteiros inteiros: int *x[10]; Para atribuir o endereço de uma variável int, chamada num, ao 5o. elemento do vetor de ponteiros: x[4]=# Para acessar a mesma posição seria: *x[4]

34 Passando Argumentos por Referência O endereço de um argumento é copiado no parâmetro formal da função. Dentro da função, o endereço é usado para acessar o argumento real utilizado na chamada da função. Isto significa que alterações feitas nos parâmetros formais afetam os argumentos usados na chamada da função.

35 Passando Argumentos por Referência void troca(int *x, int *y); main(){ int a=10; int b=20; troca(&a,&b); printf("%d %d", a,b); getch(); } void troca(int *x,int *y){ int temp; temp=*x; *x=*y; *y=temp; }

36 int a=10; int b=20; Passando Argumentos por Referência void troca(int *x, int *y); main(){ int a=10; int b=20; troca(&a,&b); printf("%d %d", a,b); getch(); } void troca(int *x,int *y){ int temp; temp=*x; *x=*y; *y=temp; } a 10 b 20

37 troca(&a,&b); void troca(int *x,int *y){ Passando Argumentos por Referência void troca(int *x, int *y); main(){ int a=10; int b=20; troca(&a,&b); printf("%d %d", a,b); getch(); } void troca(int *x,int *y){ int temp; temp=*x; *x=*y; *y=temp; } a y x 10 b 20

38 int temp; temp=*x; Passando Argumentos por Referência void troca(int *x, int *y); main(){ int a=10; int b=20; troca(&a,&b); printf("%d %d", a,b); getch(); } void troca(int *x,int *y){ int temp; temp=*x; *x=*y; *y=temp; } a y x 10 b 20 temp 10

39 *x=*y; Passando Argumentos por Referência void troca(int *x, int *y); main(){ int a=10; int b=20; troca(&a,&b); printf("%d %d", a,b); getch(); } void troca(int *x,int *y){ int temp; temp=*x; *x=*y; *y=temp; } a y x 20 b 20 temp 10

40 *y=temp; Passando Argumentos por Referência void troca(int *x, int *y); main(){ int a=10; int b=20; troca(&a,&b); printf("%d %d", a,b); getch(); } void troca(int *x,int *y){ int temp; temp=*x; *x=*y; *y=temp; } a y x 20 b 10 temp 10

41 Passando Argumentos por Referência void troca(int *x, int *y); main(){ int a=10; int b=20; troca(&a,&b); printf("%d %d", a,b); getch(); } void troca(int *x,int *y){ int temp; temp=*x; *x=*y; *y=temp; } a 20 b 10

42 Vetores como Argumento para uma Função Em C, quando um vetor é usado como um argumento para uma função, apenas o endereço do primeiro elemento do vetor é passado, não uma cópia do vetor inteiro. int i[10]; func(i); Podemos declarar o parâmetro formal de três formas: 1. void func(int *x) como um ponteiro 2. void func(int x[10]) como uma matriz dimensionada 3. void func(int x[]) como uma matriz não dimensionada Podemos verificar que o comprimento da matriz não importa para a função, porque C não realiza verificação de limites. Portanto void func(int x[30]) também funcionaria, porque o compilador C instrui func a receber um ponteiro, ele não cria realmente um vetor de 10 ou de 30 elementos.

43 Vetores como Argumento para uma Função #define Max 5 int numeros[MAX]; void mostra(int *p, int n){ for (int i=0; i

44 Vetores como Argumento para uma Função Quando um vetor bidimensional é usada como argumento para uma função, apenas um ponteiro para o primeiro elemento é realmente passado. Porém, uma função que recebe um vetor bidimensional como parâmetro, deve definir pelo menos o comprimento da 2a. dimensão. Isto ocorre porque o compilador C precisa saber o comprimento de cada linha para indexar a vetor corretamente. Exemplo: Uma função que recebe um vetor bidimensional de inteiros 10 x 10 deve ser declarada da seguinte forma: void func (int x[ ] [10]); É importante entender que, quando um vetor é usado como um argumento para uma função, seu endereço é passado para a função. Portanto existe a possibilidade do conteúdo original da vetor ser alterado. Função Retornando um Ponteiro Indicamos que uma função retornará um ponteiro inserindo um * antes do nome da função. int *func();


Carregar ppt "Prof. Ricardo Santos PONTEIROS."

Apresentações semelhantes


Anúncios Google