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:
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:
- int *ptr = numbers;
- 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.
Muito bom! Muito claro e sucinto meus parabéns amei sem enrolação.
ResponderExcluir