Buscar

Aula sobre Ponteiros em C++

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 7 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 7 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ºAula
Ponteiros – parte I
Objetivos de aprendizagem
Ao término desta aula, vocês serão capazes de: 
•	 compreender como funcionam os ponteiros;
•	 entender como usar os ponteiros.
Olá, 
Bem-vindos(as) a disciplina Estruturas de Dados I. Para 
começar os nossos estudos, vamos aprender alguns recursos que 
serão necessários para entender as estruturas que aprenderemos mais 
adiante. O primeiro recurso que vamos estudar são os ponteiros. 
Trata-se de um recurso poderoso o qual permite que você crie 
variáveis que apontem para outras, permitindo que você altere os seus 
valores. 
Como esta matéria envolve muita prática, reproduzimos muitos 
trechos de códigos para que você entenda melhor como funcionam os 
ponteiros. Para não ficar muito concentrado, este tema será dividido 
em duas aulas. Nesta primeira aula, você vai entender os conceitos 
básicos que envolvem o uso de ponteiros.
Bons estudos!
Estrutura de Dados I 6
1 - Compreendendo como funcionam os ponteiros
2 - Usando Ponteiros em Funções
1 - Compreendendo como funcionam 
os ponteiros
Antes de entendermos o que são e como funcionam 
os ponteiros, vamos ver como a memória funciona nos 
computadores. A memória é organizada em espaços 
predeterminados, onde em cada espaço abriga um dado. 
Além disso, cada espaço possui um endereço que funciona 
para localizar o dado. Podemos fazer uma analogia desse 
conceito a casas, onde possuem informações que permitem 
a sua localização, como, a rua, o bairro, o número e o CEP. 
Outra analogia que podemos fazer são com os guarda-
volumes presentes em bancos e em supermercados. Esses 
guarda-volumes, nada mais são do que armários -, abrigam 
um item que a pessoa deseja guardar. Para localizar e acessar 
o armário, nota-se que ele possui um número para a sua 
identificação.
Figura 1 – Guarda-volumes no Aeroporto de Congonhas
Fonte: <https://commons.wikimedia.org/wiki/File:Locker_in_congonhas_
airport,_s%C3%A3o_paulo..jpg>. Acesso em: 20 mar. 2018.
Quando criamos uma variável normal, reservamos um 
bloco (ou mais de um, dependendo do tipo do dado) para 
abrigar o dado. Nesse caso, caberá ao computador reservar 
um espaço da memória e gerenciá-lo, de acordo com as 
operações que nós especificamos nesse bloco. Não sabemos 
em qual posição o bloco ficará.
Figura 2 – Figura ilustrativa que mostra a alocação de 
uma variável i na memória.
Fonte: MARTINEZ, 2009, p. 325.
Seções de estudo
Porém, em algumas linguagens de programação (como 
a C++), podemos criar variáveis que abrigam endereços de 
memória, que apontam para outros blocos de memória. Isso 
se chama princípio da indireção e é a base do conceito de 
ponteiros.
Mas, como extraímos a posição de memória de uma 
variável?
Na linguagem C++, podemos saber em qual bloco 
de memória fica a variável. Podemos usar o operador & (E 
comercial) precedido do nome da variável para sabermos a 
posição do bloco de memória. Vejam esse exemplo:
Exemplo 1.1 - Testando o operador &
Vamos fazer uma pequena recapitulação: declaramos 
uma variável chamada teste e colocamos valor zero nessa 
variável (podíamos ter colocado qualquer outro valor). Em 
seguida, usamos o operador cout para exibir a posição atual 
da variável teste, com a ajuda do operador &.
Ao executar o programa, um código hexadecimal vai 
aparecer na sua tela. Não estranhe se for diferente, pois esse 
número varia a cada execução, e depende de quais blocos de 
memória estão disponíveis para uso no momento da execução.
Esse código hexadecimal é a posição (também chamada 
de endereço de memória) que está localizada a variável teste, 
no instante que o programa está sendo executado. Como já 
mencionamos, essa posição muda a cada vez que o programa 
é novamente executado. Você pode provar isso executando 
várias vezes esse mesmo programa.
Outra ideia que podemos fazer é testar isso com várias 
variáveis diferentes. No exemplo a seguir, mostramos a 
declaração de três variáveis e exibimos a posição de memória 
dessas três variáveis.
7
Exemplo 1.2 - Testando o operador & com várias 
variáveis
Agora que você já sabe como extrair a posição de 
memória de uma variável, vamos saber o que são ponteiros. 
Um ponteiro é uma variável que armazena uma posição 
de memória do sistema. Através dessa variável, podemos 
acessar a variável localizada no endereço armazenado através 
desse ponteiro.
Figura 3 – Figura ilustrativa que mostra um ponteiro p, 
que aponta para a variável i.
 
Fonte: MARTINEZ, 2009, p. 325.
Uma analogia que podemos fazer é com os atalhos para 
programas e arquivos, os quais fazemos nos computadores 
- principalmente em sistemas operacionais Windows™. 
Esses atalhos são arquivos com referências a arquivos ou a 
programas que estão em outra pasta no computador. Assim, 
esses atalhos apontam para esses arquivos.
A implementação de ponteiros é um recurso que varia 
de linguagem para linguagem. A linguagem C++ é uma das 
linguagens que permitem esse recurso. Podemos declarar 
ponteiros nessa linguagem de diversas formas. A primeira é 
a forma clássica:
Neste primeiro caso, temos uma forma similar à 
declaração de variáveis normais. A única diferença é a presença 
do asterisco (*), chamado nessa linguagem pelo nome de 
operador de indireção, pois por meio dele declaramos que 
essa variável é um ponteiro e podemos acessar o conteúdo 
presente no endereço de memória apontado por esse ponteiro.
Inicialmente, quando declaramos o ponteiro, ele terá o 
valor NULL, pois não estará apontando para absolutamente 
nada. Podemos comprovar isso escrevendo o seguinte 
programa:
Exemplo 1.3 - Testando o ponteiro, sem atribuir nenhum 
endereço de memória
Assim, para que possamos utilizar efetivamente o 
ponteiro, devemos indicar a ele qual endereço de memória 
essa variável especial apontará. Uma atribuição simples 
resolve, mas com uma pequena modificação: como a variável 
armazena endereços de memória, devemos indicar a posição 
de memória que será apontada, com o operador &:
Vale lembrar que não estamos usando o asterisco na 
variável apt, pois estamos armazenando o valor que essa 
Estrutura de Dados I 8
variável conterá - que é o endereço de memória. Se a variável 
valor estiver na posição 3625, a variável apt passará a ter o 
valor real de 3625, podendo a partir desse fato, apontar para 
a variável valor.
Assim, para que possamos exemplificar isso, vamos 
escrever um programa que:
1. declare um ponteiro para um valor inteiro, e uma 
variável do tipo inteiro;
2. atribua um valor para essa variável;
3. atribua o endereço de memória da variável para o 
ponteiro.
4. mostre na tela o valor da variável e do valor que está 
sendo apontado pelo ponteiro. Como o ponteiro 
está apontando para a variável, esperamos que os 
valores mostrados ao fim da execução sejam os 
mesmos.
Vamos ao código:
Exemplo 1.4 - Testando a atribuição de um endereço de 
memória a um ponteiro
Execute o programa e veja que o comportamento 
esperado aconteceu: os dois valores apresentados são iguais.
Nesse programa apresentado, você viu na prática o 
principal uso do operador asterisco, que serve para recuperar 
o valor contido no endereço de memória que está armazenado 
pelo ponteiro.
Através do ponteiro, você pode alterar os dados que estão 
armazenados na posição, sem a necessidade de manipular 
a variável real. O próximo exemplo, que apresentaremos a 
seguir, mostra três alterações realizadas por intermédio do 
ponteiro. A cada alteração é feita a comparação com o valor 
da variável real. Vamos ao exemplo:
Exemplo 1.5 - Testando a alteração de dados usando um 
ponteiro
Com isso, mostramos que é possível alterar dados 
presentes em uma posição de memória usando ponteiros. 
Mas, sempre devemos ter cuidado em usar o asterisco antes 
do ponteiro, para indicar que estamos usando a posição de 
9
memória referenciada por esse ponteiro.
Recapitulando
•	 para declararmos um ponteiro: int *apt;
•	 para atribuirmos uma posição de memória a esse ponteiro: apt 
= &var;
•	 para usar o valor contido na posiçãode memória apontado por 
esse ponteiro: *apt;
•	 para descobrir qual a posição de memória armazenada por esse 
ponteiro: apt;
•	 para descobrir qual é a posição de memória que está localizado o 
ponteiro - ou seja, a posição dessa variável: &apt;
Lembre-se: quando você fazer uma atribuição com valores usando 
ponteiros como intermediários, não se esqueça de colocar o 
asterisco, senão você estará alterando a posição de memória que 
vai ser apontado por esse ponteiro, o que pode causar problemas 
no seu programa.
Como já falamos, essa é a forma clássica de se lidar com 
ponteiros. A linguagem C++ permite outra forma, que realiza 
a criação do ponteiro e a alocação de um espaço de memória 
e a atribuição de um endereço de memória de uma vez só. 
Essa técnica se chama alocação dinâmica de memória. A 
sintaxe é esta:
Para testar essa variante, vamos a mais um código:
Exemplo 1.6 - Testando a segunda variante de alocação 
de ponteiros
Esse código realiza várias operações, a saber:
1. cria o ponteiro e aloca um endereço de memória 
para o tipo inteiro;
2. verifica se o ponteiro efetivamente está apontando 
para alguma coisa, verificando se o seu endereço está 
com o valor NULL. Caso seja, o programa exibe 
uma mensagem e interrompe a sua execução com o 
comando return 0;
3. se o ponteiro estiver apontando para alguma coisa, 
vamos testar uma atribuição com ele;
4. em seguida, verificamos a posição de memória 
armazenada pelo ponteiro e o valor contido na 
posição de memória, para verificar se atribuição foi 
feita de maneira correta.
Executamos esse programa e verificamos as saídas. Veja 
que uma posição de memória efetivamente foi alocada (sem 
precisar que o programador crie outra variável para isso) e seu 
endereço foi armazenado no ponteiro. A atribuição do valor 
36 por intermédio do ponteiro foi feita com êxito. 
Alocando e desalocando memória
Quando criamos uma nova variável, estamos alocando memória (ou 
seja, reservando um espaço de memória) para armazenar os dados 
dessa variável. Na forma clássica de ponteiros, fazemos duas alocações 
de memória distintas, uma para criar o ponteiro e outra para criar a 
variável que será apontada pelo ponteiro.
Nessa forma moderna, podemos fazer essas duas alocações em uma 
linha só. Criamos o espaço para o ponteiro e o espaço de memória que 
servirá para armazenar os dados, sem precisar efetivamente declarar 
outra variável para isso.
A linguagem C++, ao contrário de outras linguagens, não possui um 
mecanismo que libera memória automaticamente (como o famoso 
coletor de lixo da linguagem Java). A memória pode ser liberada de 
duas formas: encerrando o programa, o que obviamente, desalocaria 
toda a memória que o programa ocupa ou usando o operador delete, 
que desaloca o espaço de memória apontado por um ponteiro, desde 
que tenha sido criado com o operador new.
A sintaxe é esta:
delete <variável>;
delete apt;
Assim, terminamos o nosso entendimento inicial sobre 
ponteiros. Agora, vamos ver como os ponteiros funcionam 
em certas situações específicas: vamos abordar seu uso com 
funções.
Estrutura de Dados I 10
2 - Usando ponteiros em funções
Quando você iniciou seus estudos em algoritmos e na 
programação de computadores, deve ter aprendido como 
funciona a passagem de parâmetros por valor e por referência. 
Vamos retomar brevemente: A passagem por valor apenas 
transfere uma cópia do valor da variável para a função, não 
podendo alterar o valor original da função. Enquanto que a 
passagem por referência passa o endereço de memória para a 
função, podendo assim alterar o valor diretamente na variável 
original.
Podemos especificar ponteiros como parâmetros de 
funções. Quando isso acontece, devemos declarar na chamada 
da função o endereço de memória da variável que será passada 
como parâmetro. O funcionamento será igual se declararmos 
uma variável com passagem de valor por referência.
Para comprovar isso, vamos criar um programa com duas 
funções. A primeira vai trocar dois números usando a clássica 
passagem de parâmetros por referência. Já a segunda função 
vai trocar dois números por meio de ponteiros. A função 
principal executará as duas funções, usando duas variáveis 
com o mesmo valor. Vamos ao programa:
Exemplo 1.7 - Testando o uso de ponteiros em funções
Execute o programa e veja que as duas funções fazem a 
mesma coisa. Essas funções trocam valores de duas variáveis 
originais, por meio de formas diferentes.
E com isso, finalizamos a aula. Na próxima aula, vamos 
ver como funcionam os ponteiros para vetores e matrizes, 
ponteiros para ponteiros e ponteiros para registros.
Retomando a aula
Chegamos	 ao	 final	 da	 nossa	 primeira	 aula.	 Vamos	
relembrar os conceitos iniciais?
1 - Compreendendo como funcionam os ponteiros
Nessa primeira seção, vimos que os ponteiros são 
variáveis especiais que armazenam endereços de memória 
ao invés de dados. Essas variáveis servem para apontar 
para endereços de memória atribuídos a uma ou mais (ou a 
nenhuma) variáveis. Vimos o uso de dois operadores unários: 
O “E” comercial (&), que serve para extrair o endereço de 
memória de uma variável e o asterisco, que serve para declarar 
um ponteiro e para acessar um valor que está armazenado 
na posição de memória armazenada pelo ponteiro. Vimos 
também os seguintes comandos:
•	 para declararmos um ponteiro: int *apt;
•	 para atribuirmos uma posição de memória a esse 
ponteiro: apt = &var;
11
•	 para usar o valor contido na posição de memória 
apontado por esse ponteiro: *apt;
•	 para descobrir qual a posição de memória 
armazenada por esse ponteiro: apt;
•	 para descobrir qual é a posição de memória que 
está localizado o ponteiro - ou seja, a posição dessa 
variável: &apt;
2 - Usando Ponteiros em Funções
Nessa seção, vimos que podemos usar ponteiros como 
parâmetros de funções. O funcionamento nestes casos é 
semelhante a passagem de valores por referência, onde a 
função pode alterar o valor da variável usada na chamada. 
Nessas situações, devemos ter o cuidado de passar na chamada 
o endereço de memória da variável, usando o operador &.
HOLZNER, Steven; ANTUNES, Alvaro Rodrigues. 
C++ : black book. São Paulo: Makron Books do Brasil, 
2001.
JAMSA, Kris; KLANDERM LARS; SANTOS, 
Jeremias René D. Pereira dos. Programando em C/C++ : a 
bíblia. São Paulo: Makron Books do Brasil, 1999.
KENT, Jeff. C++ desmistificado. Rio de Janeiro: Alta 
Books, 2004.
MARTINEZ, Fábio Henrique Viduani. Programação de 
Computadores I. UFMS, 2009. Disponível em: <http://www.
facom.ufms.br/~montera/progiv1.pdf>. Acesso em: 19 
mai. 2018.
TENENBAUM, Aaron M.; AUGENSTEIN, Moshe 
J.; LANGSAN, Yedidyah. et al. Estruturas de dados usando 
C. São Paulo: Pearson Makron Books; São Paulo: Makron 
Books do Brasil; São Paulo: McGraw-Hill, 2013.
Vale	a	pena ler
FEOFILOFF, Paulo. Endereços e ponteiros. 2018. 
Disponível em: <https://www.ime.usp.br/~pf/
algoritmos/aulas/pont.html>. Acesso em: 19 mai. 2018.
SANCHES, Bruno Crivelari. Matrizes Dinâmicas. Ponto 
V, 2009. Disponível em: <http://www.pontov.com.br/site/
cpp/46-conceitos-basicos/57-matrizes-dinamicas>. Acesso 
em: 19 mai. 2018.
Vale	a	pena acessar
Vale a pena
Minhas anotações

Continue navegando

Outros materiais