Uma variável comum, como int x, armazena um valor, e o programa também coloca esse valor em algum lugar da memória. O nome x é um rótulo conveniente que o compilador permite usar para que você possa ler e escrever esse valor armazenado sem precisar pensar na localização física.
Essa localização ainda é importante porque a CPU, em última análise, carrega e armazena dados utilizando endereços. Mesmo quando você escreve x = 5;, o código compilado utiliza um endereço internamente para encontrar os bytes que pertencem a x e sobrescrevê-los.
Uma maneira útil de visualizar a memória é como uma longa sequência de bytes, onde cada byte possui um índice chamado endereço. Quando o compilador cria x, ele seleciona uma região de endereços grande o suficiente para acomodar um int e faz com que qualquer uso do nome x aponte para essa região.
Duas consequências decorrem desse modelo:
x, você sobrescreve os bytes na mesma faixa de endereços.y = x, geralmente obtém uma faixa de endereços separada com uma cópia do valor; assim, alterações posteriores em x não afetam y.Um ponteiro é uma variável cujo valor é um endereço. Ele não armazena o int em si, mas sim onde um int está localizado na memória, permitindo que você siga esse endereço para acessar o int.
Em C++, dois operadores tornam isso concreto:
&x // address-of (endereço de): produz o endereço onde x está armazenado
*p // dereference (desreferenciação): acessa o valor armazenado no endereço contido em p
Analise o conceito das “caixas” de memória e como o valor pode mudar enquanto o endereço permanece o mesmo.
Invariante fundamental Se
pfor igual a&x, então*prefere-se ao mesmo valor armazenado quex.
Ao armazenar um endereço, é possível compartilhar o acesso a um objeto em vez de copiá-lo. Isso ocorre em algumas situações comuns:
nullptr para indicar a ausência de um objeto, tornando essa ausência explícita no tipo.Compare os cenários de cópia e compartilhamento e observe as diferenças em termos de mutação e custo.