domenica 12 ottobre 2014

I Puntatori 2

I Puntatori - Seconda Lezione

La caratteristica alla base dei puntatori è che con essi si lavora su indirizzi di memoria, questo con il loro utilizzo comporta grandi proprietà a vantaggio del programmatore ma anche alcune possibili problematiche che potrebbero nascere dal loro utilizzo non appropriato: si potrebbe correre il rischio di andare a modificare aree di memoria riservate ad altri processi (ad esempio si potrebbe andare a modificare un area di memoria riservata al sistema operativo il che potrebbe provocare blocchi o problemi di varia natura). Proprio per questo motivo il compilatore esegue dei controlli prima di eseguire la compilazione del codice con puntatori.
Quando lavoriamo con tipi di dati primitivi (int,float,char, ecc…) il compilatore non si pone particolari riserve e cerca di fare quello che gli viene chiesto dalle istruzioni scritte dal programmatore, ma proprio per quanto detto poco fa quando si utilizzano i puntatori invece il compilatore andrà ad eseguire una serie di controlli atti ad evitare un utilizzo inappropriato.



*!* L’area di memoria valida di un puntatore è legata al tipo di puntatore dichiarato (int, float, ecc…)

Vediamo alcuni esempi:








*!* La potenza dei puntatori sta nella possibilità di poter allocare e successivamente liberare (quando non se ne ha più la necessità di utilizzo) lo spaio di memoria allocato al puntatore stesso, cosa che non può invece accadere con le variabili tradizionali (int, float, ecc…) che di conseguenza continuano a mantenere memoria allocata anche qualora non fosse più necessario.

Vediamo alcuni esempi di Codice:


#include <iostream>
using namespace std;
int main()
{
     int a=1;
     int b=10;
     int c;
     cout<<"Inserisci un valore";
     cin >> c;
     if(c>5)
     {
          a++;
          cout<<a;
     }
     else
     {
          b++;
          cout<<b;
     }
return 0;
}

In questo esempio la variabile contatore “a” o “b” viene incrementata a seconda che il valore inserito dall’utente (contenuto nella variabile “c”) sia o meno maggiore del valore 5. Ricollegandoci a quanto detto sopra possiamo vedere come in ogni caso, a prescindere dal valore dato in Input dall’utente, il compilatore allocherà spazio nella memoria per tutte e tre le variabili “a”, “b” e “c”.
Vediamo invece lo stesso esempio di codice scritto questa volta sfruttando le proprietà sopra elencate dei puntatori:

          #include <iostream>
          using namespace std;
          int main()
          {
               int *a;
               int *b;
               int c;
               cout<<"Inserisci un valore";
               cin >> c;
               if(c>5)
               {
                    a=new int;
                    *a=1;
                    *a+=1;
                    cout<<*a;
                    delete a;
               }
               else
               {
                    b=new int;
                    *b=10;
                    *b+=1;
                    cout<<*b;
                    delete b;
               }        
          return 0;
          }

In questo esempio la variabile “a” e la variabile “b” sono di tipo puntatore. Così facendo è possibile tramite l’istruzione “new int” allocare spazio in memoria per la variabile puntatore sono al momento della necessità di utilizzo della variabile senza allocare spazio a prescindere, come succede con le viste nell’esempio precedente, di conseguenza se l’utente inserirà un valore maggiore di 5 nella variabile “c” il programma allocherà memoria per il puntatore “a”, assegnerà il valore 1 all’area di memoria da esso puntata, incrementerà tale valore, visualizzerà “a” in Output e poi tramite l’istruzione delete libererà lo spazio di memoria utilizzato dalla variabile puntatore “a” da li in poi non più necessaria. 
Lo stesso procedimento verrà eseguito per la variabile puntatore “b” se il valore inserito in Input dall’utente sarà minore di 5.

Schema puntatore e indirizzi:


Schema logico di un doppio puntatore:



*!* In questo esempio la variabile puntatore “r” punta ad un indirizzo che punta a sua volta ad un altro indirizzo che contiene un dato di tipo intero.

Fonti:
Prof. Alemanno
Marchesi Giacomo

Nessun commento:

Posta un commento