C++
Home

Ponteiros

Os ponteiros são usados para conter o endereço de uma variável especifica.
Neste sentido, um nome de variável referencia diretamente um valor e um ponteiro referencia indiretamente (esse mesmo) valor.

Referenciar um valor através de um ponteiro é chamado de indireção.

Declaramos ponteiros da seguinte forma

doube *numero1;
int *numero2;

Cada variável que está sendo declarada como um ponteiro deve ser precedida de um *.
Assim sendo numero1 é um ponteiro para um double e numero2 é um ponteiro para um inteiro.

Os ponteiros podem ser inicializados com 0 ou NULL. NULL é o mesmo que 0, é uma constante definida em iostream.
O valor 0 é o único valor inteiro que pode ser atribuído diretamente a uma variável ponteiro, é mais aconselhavel usar 0 do que NULL.

O &, ou operador de endereço, é um operador unário que retorna o endereço de seu operando. É com ele que atribuimos os valores aos ponteiros.

int y = 5;
int *Py;

Py = &y;

Diz-se então, que a variável Py aponta para y.
Ao imprimir o ponteiro temos o valor real de y.

cout << *Py << endl;

Observação: O ponteiro derreferenciado(*) também pode ser usado do lado esquerdo de um comando.

*Py = 9; // atribui 9 a y

Ponteiros podem ser usados em funções, estas operações são conhecidas como chamando funções por referência.
Neste exemplo elevamos ao cubo uma variável usando uma chamada por referência com o ponteiro como argumento

// Inicializando arrays multidimensionais
#include <iostream>

using std::cout;
using std::endl;

void cubo( int * );

int main()
{
   int numero = 5;

   cout << "O valor original de numero eh " << numero;
   cubo( &numero );

   cout << "\nO novo valor de numero eh " << numero << endl;

   std::cin;

   return 0;
}

void cubo ( int *Pn )
{
   *Pn = *Pn * *Pn * *Pn;    // não confunda o sinal aritmético com o ponteiro
}

Ao longo de nosso aprendizado você vai perceber que na maioria das vezes os ponteiros são usados como argumentos de funções.
Isso acontece por que, em uma boa engenharia de softwere é melhor passar apenas um ponteiro para uma função do que uma grande quantidade de dados.

Observe que, ao usar strings por exemplo, temos o problema acima.
Observe também, que strings não são passados para funções com o & ( endereço da memória ). E que podemos manipular com os ponteiros cada caracter por vez.

Neste exemplo, vemos o uso do islower, que verifica se a letra está em minuscula, e toupper, que converte a letra para maiuscula.

#include <iostream>
using std::cout;
using std::cin;
using std::endl;

#include <cctype>

void convertU ( char * );

int main()
{
   char string[] = "palavra";

   cout << string << endl;

   convertU( string );

   cout << string << endl;


   cin;
   return 0;
}

void convertU ( char *Ps )
{
   while ( *Ps != '\0' )
   {
      if ( islower( *Ps ) )
      *Ps = toupper( *Ps );

      ++Ps; // Lembre-se que um array é um ponteiro, leia a observação com *
   }
}

É um erro de sintaxe não iniciar um ponteiro declarado com const.

* Nesta linha temos a aritmética de ponteiros. Podemos usar os seguintes sinais para realizar operações com ponteiros:

++, --, =+ e =-.

Isso só funciona com array.
Temos um array de nome numeros. E um ponteiro que aponta para esse array, mas para a posição 0, que esta na posição 300 da memória.

*ponteiro = &numero[0]; // ponteiro aponta para 300

Se somarmos vertor mais 2, na aritmética normal, teriamos 302. Mas com ponteiro é diferente.
A soma ficaria 300 + 2 * 4, resultando 308. Isto por que 4 é o sizeof de um int, o int da posição 0.

Sendo que 308 é a posição [2] do array numero. ( lembrando que o valor de int altera de máquina para máquina, podendo ser 8 ou 2. )

Assim, quando fazemos ++Ps no exercício acima, temos a seguinte operação :
pos_memoria + 1 * 4

o que leva o vetor para o próximo registro.. sendo a depois l, a, v, r, a e por fim \0

E tenho dito :)

 

Perguntas??? Email