Buscar

01-Ponteiros e Referência

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

1
Profa. Dra. Ieda Hidalgo
E-mail: iedahidalgo@ft.unicamp.br
Ponteiros 
e
Referências
2
Definição de Ponteiros
Ponteiros são variáveis cujo conteúdo são
endereços de memória. Estes endereços
podem ser, por exemplo, a localização na
memória de uma variável ou função.
Exemplo: 
se x tiver o endereço de y, 
então é dito que x "aponta para" y.
3
Para que servem os ponteiros?
� Alocação dinâmica de memória
� Manipulação de elementos de uma matriz
� Alteração do conteúdo de um argumento por
uma função
� Criação de estruturas de dados complexas,
como: listas encadeadas e árvores binárias
(onde um item deve conter referência a outro)
� Aumento de eficiência em determinadas
rotinas.
Qual o endereço de uma variável?
Todas as variáveis e funções ocupam uma certa
localização na memória, e seu endereço é o do
primeiro byte ocupado por ela.
Quando carregados para a memória, elas (as variáveis
e funções) começam em um endereço particular, e este
endereço é chamado de endereço da variável ou da
função.
5
Sintaxe da Declaração de Ponteiros
tipo *ponteiro;
tipo: determina que tipo de dados o ponteiro
estará apontando
ponteiro: é o nome da variável ponteiro
6
Exemplos
Declarar uma variável ponteiro chamada Num
que aponte para valores inteiros:
int *Num;
Na mesma instrução anterior, inicializar a
variável ponteiro Num com o endereço de x:
int *Num = &x;
7
Operadores de Ponteiros
& É um operador unário que retorna o
endereço de memória de seu operando.
* É um operador unário que retorna o conteúdo
da variável localizada no endereço especificado
pelo seu operando.
ptr = &total;
val = *ptr;
ptr recebe o endereço de memória da variável total
val recebe o conteúdo da variável localizada no endereço ptr
8
Observações
Como todas as variáveis, os ponteiros têm um
endereço e um valor.
O ato de usar um ponteiro é frequentemente
chamado de indireção, porque você está
acessando uma variável indiretamente através
de outra variável.
Tanto & quanto * têm uma precedência mais alta
do que quaisquer dos operadores aritméticos,
exceto o menos unário, com o qual eles têm
precedência igual e são resolvidos da direita
para a esquerda.
9
O tipo de um ponteiro
É importante assegurar que os ponteiros
sempre apontem para o tipo de dados correto.
Por exemplo, o fragmento a seguir está
incorreto:
int *p;
double f;
//...
p = &f; // erro de compilação
10
Coerção
Usando coerção é possível anular (a seu
próprio risco) a restrição de que dois ponteiros
devem ter tipos compatíveis. Por exemplo, o
fragmento a seguir é tecnicamente correto:
int *p;
double f;
//...
p = (int *) &f; // tecnicamente ok
11
Atribuição de valores para ponteiros
É possível usar um ponteiro no lado esquerdo de
uma instrução de atribuição para atribuir um
valor ao local apontado pelo ponteiro.
int *p; // no local apontado por p
*p = 100; // coloque o conteúdo 100
12
Alterando o conteúdo 
É possível incrementar ou decrementar o
conteúdo do local apontado por um ponteiro.
int *p; // incremente o conteúdo
(*p)++; // do local apontado por p
13
Operadores Aritméticos 
para Ponteiros
Existem 4 operadores aritméticos que
podem ser usados com ponteiros:
++ -- + -
14
Tipos de Operações Aritméticas 
para Ponteiros
� Incremento
� Decremento
� Adição de um ponteiro e um número inteiro
� Subtração de um ponteiro e um número inteiro
� Subtração de dois ponteiros.
O resultado da operação depende do tipo que
ele aponta.
15
Incremento e Decremento 
de Ponteiros
Seja p1 um ponteiro int com um valor atual de
2000, ou seja, ele contém o endereço 2000.
p1++;
Seu conteúdo será 2004 (não 2001) pois ele aponta
para a localização da memória do próximo elemento
do seu tipo base (assumindo números inteiros de
32 bits, isto é, 4 bytes de comprimento).
p1--; 
Seu conteúdo será 1996.
16
Resumindo
Sempre que um ponteiro for incrementado ele
apontará para a localização de memória do
próximo elemento do seu tipo base, sempre que
ele for decrementado, apontará para a
localização do elemento anterior de seu tipo
base.
17
Adição e Subtração de um 
ponteiro e um número inteiro
p1 = p1 + 9;
p1 apontará para o nono elemento do tipo base
de p1, após aquele para o qual ele está
apontando atualmente.
p1 = p1 – 9;
p1 apontará para o nono elemento do tipo base 
de p1, anterior àquele para o qual ele está 
apontando atualmente.
18
Subtração de Dois Ponteiros
É possível subtrair um ponteiro de outro
(desde que ambos sejam do mesmo tipo base).
O resultado será o número de elementos do
tipo base que separa os dois ponteiros.
Se um ponteiro p1 aponta para o endereço
1000, e outro p2 aponta para o endereço 1008, a
diferença entre p2 e p1 será:
� 8 se forem ponteiros do tipo char
� 2 se forem ponteiros do tipo int
� 1 se forem ponteiros do tipo double
19
Comparação entre Ponteiros
Os ponteiros de mesmo tipo podem ser
comparados usando-se operadores relacionais,
como:
== < <= > >= !=
Em geral, para que o resultado da comparação
de ponteiros seja significativo, os dois
ponteiros devem ter algum relacionamento. Por
exemplo, ambos podem apontar para
elementos de uma mesma matriz.
20
A Convenção do Ponteiro Nulo
Quando um ponteiro é declarado (antes de ser atribuído
a ele um valor) ele contém um valor arbitrário. Usar um
ponteiro não inicializado é um risco sério, pois podemos
estar acessando endereços ocupados por outros dados
ou endereços não permitidos (de uso do SO, por
exemplo).
Para evitar esse tipo de erro, os programadores em C++
adotam a seguinte convenção: se o ponteiro tiver o valor
nulo, assume-se que ele aponta para nada e não deve
ser usado.
21
Exemplo
float *p = 0; 
Para testar se um ponteiro é nulo, use uma 
instrução if: 
if (p) // ok se p não for nulo
if (!p) // ok se p for nulo
22
Múltipla Indireção
Um ponteiro para um ponteiro é uma forma de múltipla
indireção. Nesse caso, um ponteiro contém o endereço
do outro, que aponta para o local que contém o valor
desejado.
A múltipla indireção pode ser levada a qualquer
dimensão, mas raramente é necessário mais de um
ponteiro para um ponteiro.
Ponteiros para ponteiros dão a C++ uma grande
flexibilidade na criação e ordenação de classes
complexas.
23
Sintaxe / Exemplo
Sintaxe: 
int main()
{
int x, *p, **q;
x = 10;
p = &x;
q = &p;
cout << **q;
return 0;
} // Saída = 10
tipo ** ponteiro
Exemplo:
24
Dicas para evitar erros com ponteiros
Certifique-se que o ponteiro aponta para algo
antes de usá-lo, ou seja, que ele não é nulo.
Certifique-se que o tipo de objeto para o qual o
ponteiro aponta seja o mesmo que o tipo base do
ponteiro.
Faça comparações apenas entre ponteiros que
apontam para objeto comum.
Não converta ponteiros apenas para compilar seu
código (evite a coerção).
25
Ponteiros e Funções
Há três maneiras de passar
argumentos para uma função:
� Por valor
� Por referência
� Por referência com ponteiros
26
Passando Argumentos 
por Valor
Quando o envio de uma variável a uma função se dá
por valor, a função chamada cria novas variáveis do
mesmo tipo dos argumentos e copia nelas o valor
dos argumentos passados. Ou seja, a função não
tem acesso às variáveis originais, portanto não
pode modificá-las.
void inverte (int val)
…
inverte (x);
27
Passando Argumentos 
por Referência
Quando o envio de uma variável a uma função se dá
por referência, o operador de referência cria outro
nome para uma variável já existente (não uma
cópia). Nesse caso, o valor da variável enviada
pode ser alterado dentro da função.
void inverte (int &val)…
inverte (x);
28
Passando Argumentos 
por Referência com Ponteiro
Quando o envio de uma variável a uma função se dá
por referência com ponteiro, é enviado o endereço
da variável que será alterada o qual é recebido em
um ponteiro na função. Nesse caso, o valor da
variável enviada pode ser alterado dentro da
função.
void inverte (int *val)
...
inverte (&x);
• C - a passagem de parâmetros é sempre por
valor; existe o tipo "ponteiro" que permite a
você passar uma referência a um valor.
• C++ - a passagem de parâmetros é sempre
por valor; existem os tipos "ponteiro" e
"referência" que permitem a você passar
uma referência a um valor.
29
30
Retornando Ponteiros 
em uma Função
O valor de retorno de uma função deve ser
compatível com o tipo de seu retorno. Então, para
retornar um ponteiro, uma função deve declarar seu
tipo de retorno como sendo um ponteiro e o valor
usado em sua instrução return também deve ser um
ponteiro.
char *match(char c, char *s)
{
while (c != *s && *s)
s++;
return(s);
}
31
Ponteiros e Estruturas
Os tipos definidos pelo programador podem ter
ponteiros associados. A sintaxe segue a regra
geral de ponteiros.
tipo-estrutura *ponteiro;
As sintaxes para acessar os membros de uma
estrutura são:
ponteiro->membro; 
*ponteiro.membro;
32
Exemplo
struct Pessoa // declara a estrutura
{
char nome[40];
char endereço[60];
};
Pessoa *p; // declara um ponteiro para a estrutura Pessoa
p = &Pessoa; // atribui o endereço da estrutura Pessoa ao ponteiro p
p->nome; // acessa o membro nome da estrutura Pessoa
p->endereço; // acessa o membro endereço da estrutura Pessoa
33
Vantagens em usar 
Ponteiros para Estruturas
1. Permite que uma função referencie os
valores reais de uma estrutura, ao invés de
uma cópia dos seus valores.
2. Quando um ponteiro para uma estrutura é
passado para uma função apenas o
endereço da estrutura é colocado/tirado da
pilha. Isso contribui para chamadas rápidas
a funções.
34
Ponteiros Void
São ponteiros genéricos que podem ser
formatados para qualquer tipo de dado em
tempo de execução.
void * ponteiro;
35
Conteúdo do Ponteiro Void
O C++ permite que se acesse o conteúdo
apontado por um ponteiro genérico somente
após ele ser formatado. Pode-se criar outro
ponteiro e fazer a conversão de tipo na
atribuição.
int i = 5, *pi;
void *pv;
pv = &i;
pi = (int *) pv;
cout << *pi;
36
Motivação para o uso de 
Ponteiros Void
Ponteiros Void permitem especificar funções
de propósito geral cujo parâmetro é um
ponteiro a ser formatado em tempo de
execução. Isto é, com eles é possível criar
funções que retornem um ponteiro genérico e
opere independente do tipo de dado
apontado.
37
Ponteiro This
Quando criamos objetos de uma classe, cada um
deles tem sua própria cópia dos membros, mas as
funções possuem um código compartilhado por
todos os objetos da classe.
Para o programa saber dentro do código de uma
função o objeto que está sendo acessado existe um
ponteiro, denominado THIS, implicitamente criado e
associado à função. Este ponteiro aponta sempre
para o objeto que chamou a função, ou seja, sempre
aponta para o objeto sendo usado.
Quando um objeto chama uma função, o ponteiro
THIS é automaticamente ajustado para o endereço do
objeto.

Outros materiais