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

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

Linguagem de Programação VII Ponteiros

Apresentações semelhantes


Apresentação em tema: "Linguagem de Programação VII Ponteiros"— Transcrição da apresentação:

1 Linguagem de Programação VII Ponteiros
CST EM ANÁLISE E DESENVOLVIMENTO DE SISTEMA Linguagem C Linguagem de Programação VII Ponteiros Joseane Alves Freire 2º Semestre 2009

2 Introdução Ponteiros -> Apontadores
São variáveis que armazenam endereços de memória Da mesma forma que: int -> armazena um inteiro, char -> armazena um caracter, Ponteiros -> armazenam endereços de memória. Exemplo: Anotar o endereço de um colega num pedaço de papel. Neste caso o papel seria nosso ponteiro; Qual o objetivo de armazenar o endereço? Para achar o colega.

3 Introdução Ponteiros -> Apontadores
Em C armazenamos os endereços de variáveis para que elas sejam utilizadas posteriormente. Variável num Ponteiro para num num PNum num armazena um valor = 93 PNum Armazena o endereço de num = 0011. 93 93

4 Introdução Ponteiros -> Tipos
Quando se declara um ponteiro, o mesmo deve ter um tipo No C quando declaramos ponteiros nós informamos ao compilador para que tipo de variável vamos apontá-lo. Um ponteiro int aponta para um inteiro, isto é, guarda o endereço de um inteiro

5 Declaração de Ponteiros
Utilização do asterisco (*) informa ao compilador que a variável não vai guardar um valor mas sim um endereço para aquele tipo especificado Forma geral: tipo_do_ponteiro *nome_da_variável; Exemplo: int *pt; char *temp,*pt2; Ponteiro do tipo int Deve-se informar o * antes do nome da variável

6 Declaração de Ponteiros
Exemplo: int *pt; char *temp,*pt2; Nos dois exemplos anteriores os ponteiros apontam para lugares desconhecidos – PERIGO!!!!!! Portanto deve-se sempre inicializar um ponteiro para um lugar conhecido. 0 ou NULL ->ponteiros para nada. NULL mais usual int *P1 = NULL; ou int *P1 = 0;

7 Operadores de Apontamento
Além de utilizar o valor NULL, também poderíamos inicializar com o endereço de uma variável. Mas como saber o endereço da variável?? Para acessar o valor do endereço da variável basta utilizar o operador ‘&’ ‘&’ é o operador de endereçamento Exemplo:

8 Operadores de Apontamento
Agora como alterar os valores da variável para qual estamos apontando? Operador (*): operador de referência indireta Retorna cópia do CONTEÚDO de onde está apontando No exemplo anterior podíamos fazer: *apontador_y = 7; Altera o valor da variável y para 7. O operador (*) é o inverso do (&)

9 Exemplos #include <stdio.h> int main () { int num,valor; int *p;
p=&num; /* Pega o endereco de num */ valor=*p; /* Valor e igualado a num de uma maneira indireta */ printf ("\n\n%d\n",valor); printf ("Endereco para onde o ponteiro aponta:%p\n",p); printf ("Valor da variavel apontada: %d\n",*p); return(0); } #include <stdio.h> int main () { int num,*p; num=55; p=&num; /* Pega o endereco de num */ printf ("\nValor inicial: %d\n",num); *p=100; /* Muda o valor de num de uma maneira indireta */ printf ("\nValor final: %d\n",num); return(0); }

10 Operações com Ponteiros
Podemos fazer algumas operações com ponteiros p1 = p2. Neste caso estamos fazendo com que p1 aponte para o mesmo lugar que p2. *p1 = *p2. Neste caso estamos atribuindo o CONTEÚDO de *p2 a *p1. p++, p--. Neste caso estamos incrementando/decrementando posições de memória e não conteúdo. Quando incrementamos um ponteiro ele passa a apontar para o próximo valor do mesmo tipo para o qual o ponteiro aponta. Ex: se você incrementa um ponteiro char* ele anda 1 byte na memória e se você incrementa um ponteiro double* ele anda 8 bytes na memória. (*p)++, (*p)--. Neste caso estamos incrementando/decrementando o conteúdo do ponteiro. p=p+15; ou p+=15; P=p-6; ou p-=6; *(p+15). Utiliza o conteúdo do ponteiro 15 posições adiante.

11 Operações com Ponteiros
Existem operações NÃO PERMITIDAS com ponteiros Dividir ou multiplicar ponteiros. Adicionar dois ponteiros. Adicionar ou subtrair floats ou doubles de ponteiros. Exemplo: int *p1, *p2, *p3; p3 = p1*p2; p3 = p1/p2; p3 = p1+p2; p3 = p1+1.3;

12 Exercícios Qual a diferença de p++; (*p)++; *(p++) ?
O que quer dizer a expressão *(p+10) ? Qual o valor de y no final do programa? int main() { int y, *p, x; y = 0; p = &y; x = *p; x = 4; (*p)++; x--; (*p) += x; printf ("y = %d\n", y); return(0); }

13 Exercícios O que o código ao lado faz?
#include <stdio.h> #include <stdlib.h> int SomaProduto(int , int, int* ,int*); int main(){ int num1, num2, s, p; printf("Digite dois numeros:"); scanf("%d%d",&num1, &num2); SomaProduto(num1, num2, &s, &p); printf("\nA soma dos dois numeros e: %d", s); printf("\nO produto dos dois numeros e: %d\n", p); system("PAUSE"); return(0); } int SomaProduto(int n1, int n2, int *soma , int *prod){ *soma = n1 + n2; *prod = n1 * n2; if (n1 == n2) return 1; else return 0; O que o código ao lado faz?

14 Exercícios em aula O programa anterior faz:
O programa principal recebe dois números do usuário, chama a função somaProduto e mostra se os números são iguais. Além disso, mostra sua soma e seu produto. A função SomaProduto recebe dois números inteiros do usuário. Retorna 1 se os números são iguais, 0 se são diferentes. Além disso, retorna a soma e o produto dos dois números.

15 Exercícios em aula Escreva uma função CALCULA que:
receba como parâmetros duas variáveis inteiras, X e Y; retorne em X a soma de X e Y; retorne em Y a subtração de X e Y. **Pergunta: a passagem dos parâmetros para a função deve ser por valor ou por referência?

16 Uso do qualificados const
Variável não pode ser alterada. Uso do const se a função não precisar alterar uma variável. Tentativa de alteração de uma variável const produz um erro.

17 Uso do qualificados const
Ponteiros const Exemplo: int *const apont = &x; -> Ponteiro constante para um int; -> Neste caso podemos mudar o conteúdo do ponteiro, mas não o endereço de memória.

18 Uso do qualificados const
Tentativa de mudar valor – OK Tentativa de mudar endereço - ERRO

19 Uso do qualificados const
Ponteiros const Exemplo 2: const int *apont = &x; -> Ponteiro regular para um const int; -> Neste caso podemos mudar o endereço do ponteiro, mas não o seu conteúdo.

20 Uso do qualificados const
Tentativa de mudar valor – ERRO Tentativa de mudar endereço - OK

21 Ponteiros X Vetores Os ponteiros têm uma ligação muito forte com os vetores. Quando você declara um vetor tipo_da_variável nome_da_variável [tam], o compilador C calcula o tamanho, em bytes, necessário para armazená-lo O nome da variável é na verdade um ponteiro CONSTANTE para o tipo da variável do vetor. Este aponta para o primeiro elemento do vetor.

22 Ponteiros X Vetores O que significa a notação? nome_da_variável[índice] Equivale a *(nome_da_variável+índice) Desta forma: *nome_da_variável é equivalente a nome_da_variável[0] Exemplo => declaração de um array b[5] e um ponteiro bApont. bApont = b; => bApont = &b[0]; Atribuição explícita de bApont para endereçamento do primeiro elemento de b.

23 Ponteiros X Vetores Possibilidade de execução de operações de subscrição a partir do uso de apontadores. Elemento b[3]. Acesso a partir de *(bApont+3), onde 3 é o deslocamento. Acesso a partir de bApont[3] (apontador,subscrito). bApont[3] é o mesmo que b[3]. Acesso a partir de *(b+3).

24 Ponteiros X Vetores Exemplo: Array b[5].
bApont aponta inicialmente para a primeira posição do vetor: bApont=b Operação bApont += 2 move o apontador para posição elemento b[2] do vetor.

25 Ponteiros X Vetores Considere o seguinte programa para zerar uma matriz: int main () { float matrx [50][50]; int i,j; for (i=0;i<50;i++) for (j=0;j<50;j++) matrx[i][j]=0.0; return(0); } float *p; int count; p=matrx[0]; for (count=0;count<2500;count++) *p=0.0; p++; **Mais eficiente devido ao deslocamento do 1º exemplo

26 Ponteiros X Vetores Um ponteiro é uma variável, mas o nome de um vetor não é uma variável. Ou seja, não se consegue alterar o endereço que é apontado pelo "nome do vetor". int vetor[10]; int *ponteiro, i; ponteiro = &i; /* as operacoes a seguir sao invalidas */ vetor = vetor + 2; /* ERRADO: vetor nao e' variavel */ vetor++; /* ERRADO: vetor nao e' variavel */ vetor = ponteiro; /* ERRADO: vetor nao e' variavel */ /* as operacoes abaixo sao validas */ ponteiro = vetor; /* CERTO: ponteiro e' variavel */ ponteiro = vetor+2; /* CERTO: ponteiro e' variavel */

27 Ponteiros X vetores Exemplo 2. #include <stdio.h> int main () {
int matrx [10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; int *p; p=matrx; printf ("O terceiro elemento do vetor e: %d",p[2]); return(0); } **Podemos ver que p[2] equivale a *(p+2).

28 Ponteiros X Vetores Exemplo 3:
char strA[50] = "Exemplo de utilizacao de string"; char strB[50]; int main(void) { char *pA; /* ponteiro para char */ char *pB; /* ponteiro para char */ puts(strA); /* mostra strind A */ pA = strA; /* aponta pa para string A */ puts(pA); /* mostra para onde pA esta apontando */ pB = strB; /* aponta pB para string strB */ putchar('\n'); while(*pA != '\0') *pB++ = *pA++; } *pB = '\0'; puts(strB); system("PAUSE"); return 0;

29 Ponteiros X vetores Exemplo 4 : strings #include <stdio.h>
void StrCpy (char *destino,char *origem) { while (*origem) *destino=*origem; origem++; destino++; } *destino='\0';

30 Ponteiros X vetores Exemplo 4 : strings – continuando... int main () {
char str1[100],str2[100],str3[100]; printf ("Entre com uma string: "); gets (str1); StrCpy (str2,str1); StrCpy (str3,"Voce digitou a string "); printf ("\n\n%s%s",str3,str2); return(0); }

31 Vetores de Ponteiros Podemos construir vetores de ponteiros como declaramos vetores de qualquer outro tipo. int *pmatrx [10]; No caso acima, pmatrx é um vetor que armazena 10 ponteiros para inteiros. Para atribuir o endereço de uma variável var do tipo inteiro para o terceiro elemento do vetor de ponteiros pmatrx: pmatrx[2] = &var; Para obter o valor de var indiretamente no terceiro elemento de pmatrx e atribuir a uma variável y, faz-se: y = * pmatrx[2]; /* y possui o valor do terceiro elemento do vetor */

32 Vetores de Ponteiros Array de caracter
Char *naipe[4] = {“Copas”, “Paus”, “Ouro”, “Espadas”}; Cadeias de caracteres são ponteiros para o primeiro caractere. Char* => cada elemento de naipe é um ponteiro para char

33 Vetores de Ponteiros Array de caracter
Cadeias de caracteres não são realmente armazenadas no array naipe, apenas os ponteiros. O array naipe tem tamanho fixo, já as cadeias de caracteres podem ter tamanhos diferentes.

34 Vetores de Ponteiros Um vetor de ponteiros é muito utilizado nas mensagens de erro. Exemplo: #include <stdio.h> main() { char *err[] = { "mensagem1", "mensagem2", "mensagem3" }; int i; for (i = 0; i < 3; i++) puts(err[i]); }

35 Ponteiros para ponteiros
Um ponteiro para outro ponteiro é um modo de indireção múltipla. No caso de um ponteiro para outro ponteiro, o primeiro ponteiro contém o endereço do segundo, que aponta para a variável que contém o valor desejado.

36 Ponteiros para ponteiros
Declaração: tipo_da_variável **nome_da_variável; Para acessar o valor desejado apontado por um ponteiro para ponteiro, o operador asterisco deve ser aplicado duas vezes. Exemplo: #include <stdio.h> int main() { float fpi = , *pf, **ppf; pf = &fpi; /* pf armazena o endereco de fpi */ ppf = &pf; /* ppf armazena o endereco de pf */ printf("%f", **ppf); /* Imprime o valor de fpi */ printf("%f", *pf); /* Tambem imprime o valor de fpi */ return(0); }

37 Ponteiros para ponteiros
Verifique o programa abaixo. Encontre o seu erro e corrija-o para que escreva o numero 10 na tela. #include <stdlib.h> #include <stdio.h> main() { int x, *p, **q; p = &x; q = &p; x = 10; printf("\n%d\n", &q); system("PAUSE"); return(0); }

38 Ponteiros para Estruturas
Podemos declarar um ponteiro para um tipo de estrutura da seguinte forma: struct ficha_pessoal *p; Podemos utilizar este ponteiro, apontando-o para uma estrutura já existente : struct ficha_pessoal ficha; p = &ficha;

39 Ponteiros para Estruturas
Podemos também acessar um campo escrevendo: (*p)..nome Os parênteses indicam a maior precedência. Isto não é comum, o mais comum é fazer: p ->nome O operador seta ( - seguido por > ) indica que queremos o valor do campo de uma estrutura acessada por ponteiro.

40 Exemplo typedef struct { char *nome; char *endereco; long telefone;
} CLIENTE; struct CLIENTE x; x.nome = “Joaquim Mira”; x.endereco = “R. Ag.Cima, 2, Águeda”; x.telefone = ; OU CLIENTE x = {“José Boavida”, “Rua do Vau, nº 2, Viseu”, }; struct CLIENTE *x; X->nome = “Joaquim Mira”; X->morada = “R. Ag.Cima, 2, Águeda”; X->telefone = ; struct CLIENTE *x; (*x).nome = “Joaquim Mira”; (*x).morada = “R. Ag.Cima, 2, Águeda”; (*x).telefone = ;

41 Exemplo Considerando a seguinte estrutura vamos declarar um ponteiro para dez itens de produto. struct Produto { char *nome; int codigo; double preco; };

42 Exemplo #include <stdlib.h> #include <stdio.h>
typedef struct { char *nome; int codigo; double preco; }Produto ; int main(){ Produto p1[10]; Produto *p; p1[0].nome = "Pe de Moleque"; p1[0].codigo = 13205; p1[0].preco = 0.20; p1[1].nome = "Cocada baiana"; p1[1].codigo = 15000; p1[1].preco = 0.50; p = p1; //imprime posicao 0 printf("Primeiro elemento: \n"); printf("%s\n", p->nome); printf("%d\n", p->codigo); printf("%f\n", p->preco); //imprime posicao 1 printf("Segundo elemento: \n"); printf("%s\n", (p+1)->nome); printf("%d\n", (p+1)->codigo); printf("%f\n", (p+1)->preco); //ou printf("Primeiro elemento: \n"); printf("%s\n", p[1].nome); printf("%d\n", p[1].codigo); printf("%f\n", p[1].preco); system ("pause"); return (0); }

43 Retorno de uma estrutura - Recapitulando
O retorno ou saída duma estrutura : alternativa 1: retorna-se o nome da estrutura, o que implica a cópia da estrutura local da função para uma estrutura local da função invocadora (p.ex. main). alternativa 2: retorna-se o endereço da estrutura local à função para uma variável apontadora que é local à função invocadora (p.ex. main). (Veremos mais tarde).

44 Retorno através de cópia
#include <stdlib.h> #include <stdio.h> struct VECTOR{ float x; float y; }; struct VECTOR soma(struct VECTOR, struct VECTOR); int main(){ struct VECTOR p = {5.0,10.0};VECTOR q = {6.0,9.0}; struct VECTOR s; s = soma(p,q); printf("Vector soma = {%f,%f}",s.x, s.y); system ("pause"); return (0); } struct VECTOR soma(struct VECTOR a, struct VECTOR b){ VECTOR vs; vs.x = a.x + b.x; vs.y = a.y + b.y; return vs; É retornada uma CÓPIA dos dados de vs para s.

45 Retorno do endereço de uma estrutura
#include <stdlib.h> #include <stdio.h> struct VECTOR{ float x; float y; }; struct VECTOR* soma(struct VECTOR, struct VECTOR); int main(){ struct VECTOR p = {5.0,10.0};VECTOR q = {6.0,9.0}; struct VECTOR *s; s = soma(p,q); printf("Vector soma = {%f,%f}",s->x, s->y); system ("pause"); return (0); } struct VECTOR* soma(struct VECTOR a, struct VECTOR b){ static VECTOR vs; vs.x = a.x + b.x; vs.y = a.y + b.y; return &vs;

46 Variável do tipo static
Como padrão toda variável definida dentro de uma função é alocada na pilha interna de execução da função. Ao final da função a pilha é liberada, liberando assim a memória alocada pela variável. Na próxima chamada à função é feita uma nova alocação na pilha assim por diante. Deve-se indicar através da palavra static na definição de uma variável, quando for necessário que a variável local de uma função permaneça com o seu valor mantido, permitindo assim que na próxima chamada utilizar o valor anterior. No exemplo anterior é necessário declarar a variável como static pois caso contrário não conseguiríamos acessar a variável através de seu endereço, uma vez que a referência seria perdida. Compile o exemplo anterior e tente tirar o static. O que acontece??


Carregar ppt "Linguagem de Programação VII Ponteiros"

Apresentações semelhantes


Anúncios Google