appunti3s:pointers
Differences
This shows you the differences between two versions of the page.
Next revision | Previous revision | ||
appunti3s:pointers [2018/04/25 07:55] – external edit 127.0.0.1 | appunti3s:pointers [2020/06/08 22:19] (current) – external edit 127.0.0.1 | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | Attenzione: questa pagina è stata ;; | ||
+ | |||
+ | ====== Puntatori a... (qualcosa) ====== | ||
+ | =====Memoria automatica===== | ||
+ | Le variabili automatiche (cosiddette locali) sono gestite automaticamente nello //stack// e quando non servono più vengono automaticamente " | ||
+ | =====Memoria dinamica===== | ||
+ | vedere [[appunti3s: | ||
+ | |||
+ | Durante l' | ||
+ | Per riservare una zona di memoria dinamicamente si usa l' | ||
+ | < | ||
+ | L' | ||
+ | Quale tipo di dato è utile per memorizzare un indirizzo di memoria? Anche se un indirizzo di memoria è un numero, non si usa il tipo //int//, ma un tipo specifico chiamato //puntatore a...//. Nel precedente esempio si deve usare un " | ||
+ | < | ||
+ | float* numero; | ||
+ | numero = new float; | ||
+ | </ | ||
+ | |||
+ | {{: | ||
+ | |||
+ | Nel precedente esempio il programma ha riservato due aree di memoria: | ||
+ | * " | ||
+ | * "new float" come variabile // | ||
+ | Le due operazioni possono essere eseguite anche in un solo colpo: | ||
+ | < | ||
+ | La seconda variabile (nell' | ||
+ | |||
+ | < | ||
+ | |||
+ | Riassumendo, | ||
+ | * inizia la funzione | ||
+ | - definire un puntatore (nella mem. automatica) | ||
+ | - riservare la memoria dinamica con //new// e inizializzare il puntatore | ||
+ | - utilizzare a proprio piacere l'area dinamica... | ||
+ | - liberare la memoria dinamica con //delete// | ||
+ | * termina la funzione (si libera anche il puntatore) | ||
+ | Oppure, in altre parole, ricordarsi di liberare tutte le variabili dinamiche create per evitare problemi di gestione della memoria o falle (memory leak). | ||
+ | I puntatori quindi sono variabili usate prevalentemente per controllare la memoria dinamica (//heap//). | ||
+ | |||
+ | ====Un consiglio==== | ||
+ | L' | ||
+ | |||
+ | I puntatori e gli array lavorano sulla memoria a basso livello, cioè senza controlli, causando oscuri malfunzionamenti e bug! I vector invece hanno un' | ||
+ | |||
+ | Creando un vector (o uno fstream) come oggetto locale, la distruzione sarà eseguita automaticamente al termine della funzione e così si posso evitare i puntatori. | ||
+ | In ogni caso, non usare direttamente new e delete, ma creare oggetti con new nel costruttore e delete nel distruttore. | ||
+ | |||
+ | ===== Perché usare la memoria dinamica? ===== | ||
+ | |||
+ | La memoria dinamica, rispetto alla memoria automatica, può essere utile per contenere oggetti molto grandi o di dimensioni non note a priori, oppure per contenere oggetti che devono durare a lungo (più della durata degli oggetti locali (automatici) di una funzione). | ||
+ | ===== Perché usare i puntatori? ===== | ||
+ | I puntatori non vengono usati solo per accedere alla memoria heap. | ||
+ | A volte i puntatori permettono di accedere anche a zone della memoria (stack) altrimenti inaccessibili, | ||
+ | A volte i puntatori permettono di puntare alle funzioni, consentendo di eseguire funzioni diverse per condizioni diverse che si possono verificare in tempo di esecuzione (running time), in altre parole i puntatori consentono anche il [[appunti3s: | ||
+ | http:// | ||
+ | |||
+ | ===== Differenze tra puntatori e array ===== | ||
+ | < | ||
+ | In linguaggio C scrivere " | ||
+ | |||
+ | La differenza tra un puntatore (int p) è l' | ||
+ | ===== Similitudini tra puntatori e array ===== | ||
+ | < | ||
+ | Se il puntatore punta all' | ||
+ | < | ||
+ | |||
+ | Nelle dichiarazioni delle funzioni si può usare equivalentemente una qualsiasidelle seguenti due sintassi: | ||
+ | < | ||
+ | int fun(int *p);</ | ||
+ | |||
+ | ===== Puntatore appeso ===== | ||
+ | differenza tra | ||
+ | |||
+ | < | ||
+ | return & | ||
+ | // var che si autodistrugge(locale, | ||
+ | < | ||
+ | return puntatore; // restituisce un indirizzo (la copia del contenuto di | ||
+ | // un puntatore) che contiene l' | ||
+ | // un' | ||
+ | |||
+ | ===== Puntatore a void===== | ||
+ | È introdotto nel linguaggio C++ per necessità. | ||
+ | Ovviamente non esistono oggetti //void//. Il tipo //void// viene usato solo per indicare " | ||
+ | |||
+ | Il puntatore //void*// è usato solo per poter puntare qualsiasi cosa, che il programma non sa cosa sia (mentre il programmatore deve sapere cosa e'). | ||
+ | Il tipo //void*// serve solo per copiare un indirizzo di memoria a basso livello e non consente di lavorare sul contenuto della memoria. | ||
+ | |||
+ | Questo significa che per poter lavorare sul contenuto bisogna effettuare un casting verso un altro tipo di puntatore. Mentre il casting tra altri tipi può essere implicito, per i puntatori è necessario usare il casting esplicito... | ||
+ | Mentre esistono conversioni implicite tra float e int, non esiste tra float* e int* | ||
+ | |||