Buscar

ATP-Ponteiros

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 19 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 19 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 9, do total de 19 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

Algoritmos e Técnicas de 
Programação
Ponteiros (Apontadores) em C
(Prof. Wellington Lima dos Santos - UFGD)
Preâmbulo: Variáveis x Memória
� Na memória residem dados e instruções que manipulam os 
primeiros.
� Dados são armazenados e manipulados de forma mais 
conveniente em variáveis.
� Variável é um nome atribuído a um bloco de memória (alocado 
pelo compilador), no qual armazenamos e recuperamos o valor da 
variável durante a execução do programa.
� O número de bytes que o compilador reserva para a variável na 
memória depende do tipo da variável:
� char c; //1 byte
� int i; //4 bytes num SO de 32Bits
� float x; //4 bytes
� float v[5]; //5 * 4 = 20 bytes
� float m[5][6]; //5 * 6 * 4 = 120 bytes
Ponteiros - Introdução
� Ponteiro é uma variável, cujos valores são endereços de 
memória, ou seja, posições dos bytes da memória.
� Estes endereços são inteiros 32 ou 64 bits (conforme o S.O.), 
porém tratados distintamente do tipo int para que operações 
matemáticas indevidas sejam evitadas.
� Ponteiros são usados para armazenar o endereço de:
� Outra variável, de qualquer tipo, incluindo ponteiros.
� Bloco de memória dinâmica alocada com malloc.
� Uma função, permitindo passá-la como parâmetro para funções.
� Ponteiros permitem livre acesso à memória, portanto 
Cuidado!
� Ponteiros permitem representar estruturas de dados 
dinâmicas muito úteis como listas encadeadas e árvores.
Ponteiros - Introdução
� “O correto entendimento e uso de ponteiros é crítico 
para uma programação bem-sucedida em C.”
(SCHILDT, H. C Completo e Total)
� Em C, ponteiros têm quatro usos importantes:
� Passagem de parâmetros por referência para funções.
� Suporte à alocação dinâmica de memória e ao uso de 
estruturas de dados complexas.
� Passagem de funções como parâmetros para outras 
funções.
� Otimização de algumas rotinas, aumentando sua 
eficiência.
Declaração de Ponteiros
� PONTEIRO TIPADO: faz com que compilador interprete a 
memória apontada como o primeiro byte de uma variável 
associada ao tipo do ponteiro.
� Se pensarmos em um tipo como uma máscara de bits para a 
memória ocupada por uma variável desse tipo, então um 
ponteiro tipado funciona como uma máscara “deslizante”
sobre os bytes da memória, possibilitando interpretar seus 
bits conforme os seus significados para o tipo. 
� Sintaxe de declaração: 
� tipobase * NomeVar; 
� Exemplos:
� int * i; //ponteiro para um dado int
� char * s; //ponteiro para um dado char
� float * x; //ponteiro para um dado float
Declaração de Ponteiros
� PONTEIRO TIPADO: faz com que compilador interprete a 
memória apontada como o primeiro byte de uma variável 
associada ao tipo do ponteiro.
� Um TIPO de dado define como devem ser interpretados os 
bits na memória ocupada por uma variável desse tipo. De 
outro modo, um tipo funciona como uma máscara de bits.
� Assim, um ponteiro tipado funciona como uma máscara 
“deslizante” sobre os bytes da memória, dando significados 
aos seus bits conforme o tipo do ponteiro. 
� Sintaxe de declaração: 
� TipoVar * NomeVar; 
� Exemplos:
� int * i; //ponteiro para um int
� char * s; //ponteiro para um char
� float * x; //ponteiro para um float
Declaração de Ponteiros
� PONTEIRO GENÉRICO: Nenhum tipo é associado ao 
ponteiro, portanto o compilador não tem informação sobre 
como interpretar os bits da memória apontada.
� Desta forma conhecemos apenas o endereço inicial do bloco 
de memória mas não o seu significado.
� Comumente é usado para armazenar endereços de grandes 
blocos de memória dinâmica obtida com malloc, nos quais se 
escrevem informações heterogêneas. 
� Sintaxe de declaração: 
� void * NomeVar; 
� Exemplos:
� void * p; //ponteiro genérico
� void * temp; //ponteiro genérico
Operadores de Ponteiros: & e *
� & ⇒⇒⇒⇒ Retorna o endereço da variável que o segue.
� Exemplo:
� No que k e x (e os demais, se existissem) são parâmetros 
passados por referência!
int k;
float x;
scanf(“ %d , %f ” , &k , &x );
formata a 1a entrada como inteiro
e armazene-a no endereço de k
formata a 2a entrada como float
e armazena-a no endereço de x
Operadores de Ponteiros: & e *
� * (asterisco) ⇒⇒⇒⇒ Permite acessar o conteúdo 
(geralmente referido como valor apontado) 
da variável que o sucede. 
� Exemplo:
#include <stdio.h>
#include <conio.h>
int main(int argc, char* argv[])
{ int k;
int * p;
p = &k; //faz p apontar para o endereço de k
k = 25;
printf("%d\n", *p); //imprime o valor 25
*p = *p + 20; //faz: k = k + 20
printf("%d\n", k); //imprime o valor 45
}
Aritmética de Ponteiros
� Considerando as declarações em C: 
� TipoVar * p;
� int k;
� São possíveis as seguintes operações:
� p++⇒ incrementa o endereço de p em
(sizeof(TipoVar)) bytes.
� p-- ⇒ decrementa o endereço de p em
(sizeof(TipoVar)) bytes.
� p ± k⇒ retorna outro ponteiro cujo endereço é
deslocado de (±k * sizeof(TipoVar)) bytes.
Aritmética de ponteiros: Exemplo1
#include <stdio.h>
void main()
{ int v[] = {111, 222, 333, 444, 555, 666};
int * p;
p = &v[1]; //p aponta para o 2o elemento: 222
printf("%d\n", *p); //imprime 222
p++; //avança para v[2]: 333
printf("%d\n", *p); //imprime 333
printf("%d\n", *(p+3)); //imprime 666
p = p - 2; //volta p/ v[2-2=0]:111
printf("%d\n", *p); //imprime 111
}
Aritmética de ponteiros: Exemplo2
void InverteVetor (int v[], int n)
{ int *e, *d, t;
e = v; //o mesmo que: e = &v[0]
d = &v[n-1]; //aponta para o último elemento
while (e < d) //enquanto “e” não cruzar “d”
{
t = *e;
*e = *d;
*d = t;
e++; //avança um int para a direita
d--; //recua um int para a esquerda
}
}
� Inversão da ordem de um vetor:
0 1 2 3 n-2 n-1
•••
⇑ ⇑
e d
Alocação Dinâmica: Exemplo
� Uma função genérica para trocar o conteúdo de duas 
variáveis do mesmo tipo
//memcpy requer <mem.h>
void TrocaVars(void * a, void * b, int sz)
{ void * c;
c = malloc(sz); //aloca "sz" bytes
memcpy(c, a, sz); //copia de "a" para "c"
memcpy(a, b, sz); //copia de "b" para "a"
memcpy(b, c, sz); //copia de "c" para "b"
free(c); //desaloca a memória
}
Alocação Dinâmica: Exemplo (Cont.)
� Uso da Função TrocaVars
#include <stdio.h>
#include <stdlib.h>
#include <mem.h>
void main()
{ char r = 'A', s = 'Z';
int x = 25, y = 80;
printf("r = %c s = %c \n", r, s);
TrocaVars(&r, &s, sizeof(r)); //troca os valores de "r" e "s"
printf("r = %c s = %c \n", r, s);
printf("x = %d y = %d \n", x, y);
TrocaVars(&x, &y, sizeof(x)); //troca os valores de "r" e "s"
printf("x = %d y = %d \n", x, y);
}
Ponteiros para funções
� Um ponteiro para uma função pode ser declarado da seguinte 
forma:
TipoRet (* NomePonteiro) (tipo1, tipo2, ..., tipoN)
� TipoRet⇒ tipo retornado pela função
� NomePonteiro⇒ nome da variável ponteiro precedido de *, ambos 
entre ( ), obrigatoriamente.
� tipo1, tipo2, ..., tipoN⇒ tipos de cada um dos N 
parâmetros formais da função.
� Como num protótipo, os nomes dos parâmetros não interessam.
� Assim, para definir um ponteiro para uma função basta copiar o 
seu protótipo e substituir nele o nome da função por
( * NomePonteiro)
Ponteiros para funções - Exemplo
int Soma(int a, int b)
{ return a + b;}
int Mult(int a, int b)
{ return a * b; }
int Executa(int x, int y, int (* func) (int, int))
{ return func(x, y); }
void main()
{ //declara um ponteiro compatível com “Soma” e “Mult”
int (*func)(int, int);
//o endereço é obtido pelo nome sem parâmetros e sem &
func = Mult;
printf("%d", func(3, 7)); //imprime 3 x 7 = 21
func = Soma; //atribui a func o endereço de Soma
printf("%d", Executa(4, 5, Soma)); //imprime 4 + 5 = 9
}
Exercício 1:
� Quais são os dois valores exibidos na tela pelo programa 
abaixo?
void main()
{ int a = 30;int * p;
p = &a;
a = a + 15;
printf("%d\n", *p);
*p = *p + 5;
a++;
printf("%d\n", a);
}
Exercício 2:
� Que valor é exibido na tela pelo programa abaixo?
void main()
{ float x[] = {2.5, 3.6, 1.2, -99.9};
float * y;
y = &x[2];
y++;
*y = *(y-2) + *(y-1);
printf("%.1f\n", x[3]);
}
Exercício 3:
� Quais são os dois valores exibidos na tela pelo programa 
abaixo?
void main()
{
int v[] = {000, 111, 222, 333, 444, 555, 666};
int *i;
int **j;
j = &i;
i = v + 5; // mesmo que: i = &v[0] + 5
*j = *j - 3;
printf("%d\n", *i);
i++;
printf("%d\n", **j);
}

Outros materiais