Site icon Embarcados – Sua fonte de informações sobre Sistemas Embarcados

Ponteiro em C: Aritmética de ponteiro

funções X macros compilação condicional Diagnóstico

Continuando o assunto abordado no primeiro artigo, veremos algumas aplicações envolvendo aritmética de ponteiro. Assim como variáveis comuns, os ponteiros também podem ter o seu conteúdo alterado utilizando operações aritméticas, contudo é necessário entender mais alguns conceitos.

Variáveis

Vimos no primeiro artigo que ao declarar uma variável, um espaço na memória é reservado. Neste ponto, é importante definir que toda variável declarada ocupa uma porção da memória, sendo que o tamanho ocupado é relativo ao tipo da variável. Um modo de obter o tamanho que um tipo de dado representa é a partir do operador sizeof. Para exemplificar, considere o código abaixo que foi executado em uma máquina de 64 bits.

A saída gerada é mostrada na Figura 1. Cabe ressaltar que o comando sizeof retorna o tamanho em bytes!

Figura 1: Tamanho em bytes para diferentes tipos de dados.

Se considerarmos uma memória endereçada byte a byte, a declaração de uma variável do tipo inteiro ocuparia 4 bytes da memória, já um double, 8 bytes. Diante disso, consideramos como endereço da variável o endereço de menor valor na região ocupada. Na Figura 2, o endereço base é indicado em vermelho.

Figura 2: Exemplo de variáveis na memória.

É importante lembrar que um ponteiro também é uma variável, portanto ocupa espaço na memória. Geralmente, o tamanho de um ponteiro, independente do tipo de dados, ocupa o espaço de um inteiro.

Portanto, ao acessar o conteúdo de um endereço o tipo de dado deve ser considerado, pois diferentes tipos podem ocupar espaços diferentes da memória. Essas definições são importantes, pois um ponteiro também possui um tipo de dados e isso implicará nas operações aritméticas realizadas!

Operações com ponteiros

Apenas as operações de subtração e adição podem ser realizadas com os ponteiros. Como veremos a seguir essas operações dependem do tipo de dados que o ponteiro foi declarado. Este tópico é importante para entender a utilização de ponteiros com vetores e matrizes.

Apresentando as operações básicas de incremento e decremento fica fácil entender o que ocorre com o endereço armazenado no ponteiro quando uma das operações aritméticas é utilizada. Considere o caso mostrado na Figura 3.

Figura 3: Ponteiro do tipo inteiro apontando para uma variável.

Neste exemplo, temos um ponteiro e três variáveis do tipo inteiro. Considere também que essas variáveis estão alinhadas sequencialmente na memória e que o ponteiro está armazenando o endereço da variável x (endereço 104).

Para incrementar o ponteiro:

Lembre-se que é o endereço armazenado no ponteiro que desejamos incrementar. Ao realizar a operação, o ponteiro passará a apontar para o próximo dado do seu tipo. Dito de outra maneira, ao incrementar o ponteiro o seu valor é alterado conforme o tamanho do tipo de dado que ele aponta. Diante disso, o próximo valor pt é o endereço 108, logo o ponteiro aponta para a variável y. Essa situação é ilustrada na Figura 4.

Figura 4: Operação de incremento.

O mesmo ocorre para a operação de decremento:

Neste caso, o ponteiro passa a apontar para o elemento anterior. De maneira geral, qualquer operação aritmética de ponteiro será realizada conforme o seu tipo base.

Por exemplo:

Essa operação faz com que o ponteiro seja deslocado 16 bytes, ou seja, quatro elementos adiante.

Comparação de Ponteiros

A comparação de ponteiro também pode ser realizada, isto é, os endereços armazenados podem ser utilizados numa expressão relacional. Uma operação simples é a de diferenciação, ou seja, quando um ponteiro é subtraído de outro.

Com a diferenciação é possível obter a distância entre os dois ponteiros, isto é, a quantidade de elementos presentes. Diante disso, é comum que as operações de comparação sejam realizadas quando os ponteiros apontam para um objeto comum [1].

Conclusão

Os tópicos discutidos neste artigo são de grande importância para trabalhar com ponteiros e arrays. Como demonstrado, qualquer operação aritmética de ponteiro é realizada conforme o seu tipo base. Além disso, os ponteiros podem ser comparados em uma expressão relacional. Essas características possibilitam criar e manipular estruturas de dados bem mais complexas, contudo, vale lembrar que todo cuidado é pouco ao trabalhar com ponteiros!

Referências

[1] – Livro: C, completo e total – 3ª edição revista e atualizada. Herbert Schildt.

Fonte da imagem destacada: http://listamaze.com/top-10-programming-languages-for-job-security/

Outros artigos da série

<< Ponteiro em C: DefiniçãoPonteiro em C: Arrays >>