Ajude nosso projeto a se manter online.

Ponteiros, Arrays e Aritmética

Dando continuidade ao estudo dos ponteiros, vamos ver a importante relação deles com os arrays, bem como aprender a manipular aritmeticamente os ponteiros, com operações matemáticas.

Arrays e Ponteiros, Ponteiros e Arrays

Por curiosidade, vamos declarar um array de inteiros, de nome 'numbers', inicializar e depois simplesmente imprimir o valor '*numbers':
#include <iostream>
using namespace std;

int main()
{
    int numbers[]={1, 2, 3, 2112};

    cout << *numbers << endl;

    return 0;
}
Olha que interessante o resultado:
Curso de C++ online grátis, com apostila para download

Ou seja: o nome do array funciona como um ponteiro.
E para onde ele aponta? Para o primeiro elemento do array.

Assim, sempre que tivermos um array de nome: arr
Se usarmos o nome da variável do array, ela vai se comportar como um array que aponta para: arr[0]

E para apontar para os demais membros do array?
Lembre-se da seguinte regra:
  • arr[indice] = *(arr + indice)

Ou seja:
arr[0] pode ser referenciado por *(arr + 0)
arr[1] pode ser referenciado por *(arr + 1)
arr[2] pode ser referenciado por *(arr + 2)
...
arr[n] pode ser referenciado por *(arr + n)

Podemos fazer um ponteiro de nome 'ptr' apontar para o primeiro elemento de um array das seguintes formas:
  1. int *ptr = numbers;
  2. int *ptr = &numbers[0];

Vamos imprimir todo um array, usando apenas um ponteiro:
#include <iostream>
using namespace std;

int main()
{
    int numbers[6]={1, 2, 3, 4, 5, 2112},
        *ptr = numbers;

    for(int aux=0 ; aux<6 ; aux++)
        cout << *(ptr+aux) << endl;

    return 0;
}

Aritmética dos Ponteiros

No exemplo de código C++ anterior, você viu que fizemos várias vezes uma operação de adição com ponteiros: ptr+aux, onde aux é uma variável inteira que foi de 0 até 5, para percorrer o array.

Poderíamos ter feito o mesmo programa com o operador ++, veja:
#include <iostream>
using namespace std;

int main()
{
    int numbers[6]={1, 2, 3, 4, 5, 2112},
        *ptr = numbers;

    for(int aux=0 ; aux<6 ; aux++){
        cout << *ptr << endl;
        ptr++;
    }

    return 0;
}
Ou seja, cada vez que adicionamos uma unidade ao ponteiro (++), ele aponta para o próximo elemento do array. Podemos fazer o inverso, apontar para o último elemento do array e irmos decrementando:
#include <iostream>
using namespace std;

int main()
{
    int numbers[6]={1, 2, 3, 4, 5, 2112},
        *ptr = &numbers[5];

    for(int aux=5 ; aux>=0 ; aux--){
        cout << *ptr << endl;
        ptr--;
    }

    return 0;
}
Poderíamos usar também os operadores -= ou +=

A lógica é a seguinte.
Quando apontamos o ponteiro para o array, ele vai apontar para o endereço de memória do primeiro elemento. Vamos supor que seja o bloco de memória 1000.

Quando fazemos: ptr++
Ele não incrementa o endereço de memória em uma unidade, ele não vai pra 1.
Ele vai para: 1000 + sizeof(int)

Como o array é de inteiros, cada bloco do array ocupa 4 Kbytes, logo ptr vai apontar para o endereço 1004. Depois para o bloco 1008, depois 1012...

Se o array fosse de double, ele ia apontar para os endereços: 1000, 1008, 1016, 1024...a cada vez que incrementássemos, pois a variável double ocupa 8 Kbytes.

Veja como fica o código do programa que imprime apenas os elementos de índice par, do array (0, 2 e 4):
#include <iostream>
using namespace std;

int main()
{
    int numbers[6]={1, 2, 3, 4, 5, 2112},
        *ptr = numbers;

    for(int aux=0 ; aux<3 ; aux++){
        cout << *ptr << endl;
        ptr += 2;
    }

    return 0;
}
Essa é a lógica e matemática dos ponteiros. Por isso é tão importante definir o tipo de ponteiro (int, char, double...), pois os ponteiros apontam para blocos inteiros de memória, o tamanho desses blocos variam de acordo com o tipo de dado.

Nenhum comentário:

Postar um comentário