Teoria

Introdução

Fala aí, aqui é o Guga do Responde Aí! Tudo bem com você?

No tópico anterior nós vimos o conceito de apontadores e aprendemos como declará-los na linguagem C, agora nós iremos conversar um pouco sobre a manipulação de ponteiros em alguns casos comuns em que eles são utilizados.

Obtendo o dado de um ponteiro

O caso mais básico e, que iremos ver primeiro, é como obter o dado de um ponteiro, mas esse dado não é o endereço em sí que ele armazena e sim o dado alocado nesse endereço de memória.

A imagem a seguir ilustra a declaração de um ponteiro ptrX:

O que nós faríamos se quiséssemos imprimir o dado alocado no endereço de memória para o qual o ponteiro ptrX aponta?

A solução é muito simples, basta observarmos essa imagem:

Nela podemos ver que só precisamos utilizar o operador * (ele é utilizado para muitas coisas mesmo) antes do ponteiro. Isso fará com que o valor que é acessado seja o dado armazenado no endereço de memória que é apontado pelo endereço que está armazenado no ponteiro. Ou seja, nesse caso ao invés de ser impresso o endereço na memória em que X está armazenado, será impresso o valor 3.1416 que é o dado armazenado na memória exatamente no endereço para o qual ptrX aponta.

Ponteiros como parâmetro de funções

Ponteiros como parâmetros de funções são muito comuns, pois como se trata de endereços, criamos uma forma de alterar o dado presente nesse endereço mesmo quando a alteração é feita dentro do escopo de uma função.

Mas por que isso acontece?

Pois a variável de cópia criada pela função em seu escopo local terá o mesmo endereço de memória que a variável original. Ou seja, alterações tanto no programa principal, quanto em uma função estão alterando o mesmo endereço de memória, consequentemente a mesma variável.

Estranho, né? Olha como isso funciona em um código de verdade:

Nesse código, o endereço da variável X foi passado como parâmetro da função incrementa (linha 09), essa por sua vez incrementou o valor armazenado nesse endereço de memória em uma unidade. Porém, apesar de tal alteração ter sido feita em escopo local (dentro da função incrementa), por se tratar de uma manipulação por endereço de memória, a impressão feita na linha 10 (após a função ter sido invocada) teve o seguinte resultado:

Sendo assim, podemos concluir que o valor da variável original também foi alterado.

Então lembre-se, sempre que se uma manipulação é feita através de um endereço de memória, todas as instâncias que compartilham essa memória são alteradas. Nesse exemplo, tanto a variável no escopo principal, quanto a variável no escopo local tiveram seus valores alterados.

Presta muita atenção porque isso cai como pegadinha sempre nas provas de programação, hein!?

Ponteiros duplos

Ponteiros duplos costumam confundir muito a cabeça, basicamente são ponteiros que apontam para outros ponteiros.

Para entendermos melhor, vamos observar essa imagem:

Nela nós temos um ponteiro pt2 que aponta para o endereço de outro ponteiro, o pt1, que por sua vez aponta para o endereço de uma variável V, essa que armazena o valor 100.

Em termos de código, isso acontece da seguinte forma:

A grande novidade está na declaração de um ponteiro duplo (linha 08 do código acima), em que basicamente o operador * é utilizado 2 vezes para sinalizar que aquela variável irá apontar para um endereço de memória que contém um ponteiro que aponta para outro endereço de memória. Além disso, esse ponteiro duplo é inicializado com o endereço de memória de pt1 (ponteiro que aponta para a variável V).

E se nós quiséssemos imprimir o valor da variável V a partir do ponteiro pt2? A lógica é a mesma, nós só precisamos nos atentar a sintaxe dos acessos (primeira coisa vista nesse tópico).

Para entendermos melhor, vamos observar a imagem a seguir:

Basicamente essa sintaxe acessa o valor apontado por pt2 (que é pt1), em seguida acessa o valor apontado por pt2 (que é a variável V). Para isso, é necessário a utilização do operador * duas vezes, que corresponde aos dois acessos descritos anteriormente.

Agora que nós já sabemos o básico sobre manipulação de vetores, está na hora de aprendermos ainda mais com os exercícios de fixação!

Ponteiros como parâmetro de funções

Ponteiros duplos