Linguagem de Programação VII Ponteiros

Slides:



Advertisements
Apresentações semelhantes
Laboratório de programação III Linguagem C
Advertisements

Linguagem de Programação VI Tipos de Dados Compostos - structs
Construção de Algoritmos AULA 07
Programação II Estruturas de Dados
Programação II Estruturas de Dados
Algoritmos e Estrutura de Dados I
ICC – Matrizes Jorge Macêdo.
Alocação Dinâmica de Memória
AULA – Linguagem C – Vetores, Ponteiros Estruturas
LPG - I: Ponteiros e Vetores/Matrizes UDESC - SBS
Universidade Federal do Espírito Santo Programação II Estruturas Professora: Norminda Luiza.
Linguagem C Strings.
Ponteiros em Linguagem C
Slides Prof. Jean SIMÃO Revisão: Prof. João FABRO
Linguagem C Strings.
Armazenamento de Dados em Arquivos
Matrizes e Funções - Continuação
Fundamentos de Programação 1
Ponteiros.
Escola Secundária c/ 3º CEB da Batalha
Listas Encadeadas.
Revisão da Linguagem C.
Apontadores ou Ponteiros
APRESENTAÇÃO: GIANCARLO DE GUSMÃO GONÇALVES CURSO DE C AULA 08: Tipos Estruturados.
Aula prática 8 Ponteiros Monitoria de Introdução à Programação
Aula prática 8 Ponteiros Monitoria de Introdução à Programação.
Aula prática 6 Vetores e Matrizes
PROGRAMAÇÃO ESTRUTURADA II
PROGRAMAÇÃO ESTRUTURADA II
Linguagem de Programação II Parte VII
Definição de Tipos Estruturas e Ponteiros
CADEIA DE CARACTERES (Strings)
Estrutura de dados II Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação.
Linguagem de programação I A Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação.
Professor Mário Dantas
Prof. Ricardo Santos PONTEIROS
Curso de C/C++ Aula 2 Instrutor: Luiz Felipe Sotero
Linguagem C : Ponteiros
Estruturas de Dados Aula 2: Estruturas Estáticas 07/04/2014.
Educação Profissional Técnica de Nível Médio Curso Técnico de Informática
Aula P.02 – BCC202 Revisão sobre Ponteiros Túlio Toffolo
Algoritmos e Estruturas de Dados
Joaquim José Hangalo  Podemos entender a memória do computador como um conjunto de células que armazenam informações.  Cada célula.
STRINGS Dilvan Moreira (baseado no livro Big Java e Z. Liang)
Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores
Linguagem de programação I A Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação Versão: _01.
Linguagem de programação I A Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação Versão: _01.
Linguagem C.
CES-10 INTRODUÇÃO À COMPUTAÇÃO
Algoritmos e Programação MC102 Prof. Paulo Miranda IC-UNICAMP Aula 15 Ponteiros.
INE - UFSC - Disciplina Estruturas de Dados - Prof. Dr. Aldo von Wangenheim Página 1 Estruturas de Dados - T.332 Capítulo 3 Parte 1: Ponteiros, Passagem.
Programação Computacional Aula 8: Entrada e Saída pelo Console Prof a. Madeleine Medrano
Algoritmo e Estrutura de Dados I Aulas 12 – Linguagem C Strings Márcia Marra
Profa. Maria Augusta Constante Puget
Linguaguem de Programação II
Estrutura de Dados Revisão Professor Luiz José Hoffmann Filho
 O que são arrays:  estruturas de dados homogêneas  coleção de elementos do mesmo tipo referenciada por um nome comum  um array pode ser imaginado.
Estruturas Homogêneas – Vetores e Matrizes
Profa. Maria Augusta Constante Puget
Algoritmo e Estrutura de Dados I Aulas 15 – Linguagem C Alocação Dinâmica de Memória Márcia Marra
Algoritmo e Estrutura de Dados I Aulas 14 – Linguagem C Matriz Márcia Marra
Linguagem de Programação
ponteiros Estrutura de Dados Prof. André Cypriano M. Costa
Fundamentos de Programação 1
Aula Prática 6 Ponteiros Monitoria  Quando declaramos uma matriz:  tipo meuArray[tam];  O compilador aloca a matriz em uma região de memória.
Estrutura de Dados STRUCTS Dilvan Moreira. Objetivos  Entender o que são e como usar:  Estrutura de Dados para a Linguagem C  Structs (Registros)
Estruturas Homogêneas - Vetores
1 Aula 07 Strings Prof. Filipe Mutz. 2 Em nossos programas ainda não vimos como armazenar palavras e textos, e eles são muito importantes! Exemplos: Programas.
FUNÇÕES Dilvan Moreira (baseado em material de Z. Liang)
Transcrição da apresentação:

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

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.

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

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

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

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;

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:

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 (&)

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

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.

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;

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

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?

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.

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?

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.

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.

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

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.

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

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.

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.

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

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.

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

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

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

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;

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

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

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

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

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.

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

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.

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 = 3.1415, *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); }

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

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;

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.

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

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

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

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

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.

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;

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??