Un puntatore è una variabile che contiene un indirizzo di memoria. Sono estremamente utili (direi indispensabili) ogni qual volta che hai bisogno di accedere a particolari strutture, senza preoccuparti di dover creare sufficienti variabili per loro. Supponiamo, infatti, che tu non sappia a priori di quante variabili hai bisogno...

Vediamo di fare un esempio pratico: immagino che tu abbia lavorato, qualche volta, con gli array. Il classico programmino per ordinare un array l'avrai già fatto. Qual è il limite che hai incontrato finora? Senza dubbio il fatto di avere un array di dimensioni limitate ad un certo massimo di elementi. Questo limite si traduce, a volte, come qualcosa di restrittivo (se devo aver a che fare con un array più grande come faccio? riscrivo il programma e lo ricompilo); ma a volte si traduce solo in uno spreco di memoria (dichiari un array di dimensione 100 come massimo, quando l'utente ha bisogno di ordinare solo 10 elementi...).
Come si ovvia a questi (nota: grossi) problemi? I puntatori arrivano in soccorso: dichiari una variabile come puntatore a valori interi e chiedi all'utente di quanti elementi ha bisogno. Quindi crei la struttura adatta a contenerli (allochi abbastanza memoria) e li vai a indirizzare (ossia li raggiungi) tramite il puntatore.

Questo è un banalissimo esempio, ma la loro importanza la capirai quando dovrai far tornare dei valori a delle funzioni, oppure rendere permanenti dei cambiamenti a variabili, effettuati all'interno di procedure (quando inizierai a vedere gli oggetti, poi...)

Vediamo l'esempio di prima: come creare un array dinamico...
codice:
#include <iostream>
using namespace std;

int main() {
   int *mioArray;  /* Questo è un puntatore ad intero: sarà l'array */
   int *copia;     /* Questo mi serve solo per tenere traccia del primo elemento */
   int lunghezza;  /* conterrà la lunghezza dell'array che chiedo all'utente */
   int i;

   cout << "Introduci la lunghezza dell'array: ";
   cin >> lunghezza;

   /* Ora creiamo lo spazio in memoria per l'array */
   mioArray = (int*) malloc( lunghezza * sizeof(int) );
   copia = mioArray;

   /* riempiamo l'array con dei valori numerici */
   for(i=0; i<lunghezza; i++) {
      *mioArray = i;  /* In questo modo accedo all'elemento attualmente puntato dal puntatore */
      mioArray++;  /* incremento il puntatore: andrà a puntare alla locazione successiva */
   }

   /* Stampiamo l'array */
   for (i=0; i<lunghezza; i++) {
      cout << "Elemento di indice " << i << ":  " << *copia;
      copia++;
   }
}
Ciao.