Utilizzo di VariablesEdit
Visibilità e durata di VariablesEdit
Le variabili possono avere visibilità o ambito diversi, a seconda di come vengono dichiarate e utilizzate. Ambito si riferisce alla possibilità di accedere al contenuto di una particolare variabile in un determinato punto del programma.
Di solito, l’ambito di una variabile è determinato dal suo blocco che lo racchiude. Un blocco può essere racchiuso esplicitamente in alcune lingue (begin / end, { / } pairs), mentre in altre il blocco è implicito.
Quasi tutte le lingue hanno un ambito di delimitazione generale e, se un programma dichiara una variabile in questo ambito, è nota come variabile globale.
Una variabile locale, al contrario, è visibile solo, o “in ambito”, all’interno del suo blocco.
Considera questo codice:
integer globalVariableglobalVariable = 5begin integer localVariable localVariable = 7 globalVariable = 8endlocalVariable = 3 /* <-- this is a syntax error */
la variabile globale è dichiarata al di fuori di qualsiasi blocco, quindi è nell’ambito globale (implicito), rendendolo una variabile globale. la variabile locale viene dichiarata nel blocco begin/end, limitando il suo ambito a quel blocco.
La variabile globalVariable inizia come 5, viene assegnato 8 nel blocco ed esce come 8. La variabile localVariable viene assegnata 7, quindi esce dall’ambito prima di essere assegnata illegalmente 3. Non esiste una variabile localVariable a questo livello.
La durata di una variabile indica quando la variabile è attiva. Nell’esempio precedente, una variabile globale viene creata all’inizio del programma e ha una durata pari alla lunghezza del programma. Per localVariable, non viene creato fino a quando non inizia la direttiva del blocco. La sua vita è finita quando il programma passa la direttiva finale.
Dynamic memory allocationEdit
Molti programmi hanno scopi molto specifici e necessitano di aree molto specifiche e piccole per la memoria. Se stessimo scrivendo un programma per la lettura di file di immagine, non siamo sicuri esattamente quanto grande le immagini potrebbero essere. Alcuni potrebbero essere centinaia di megabyte, mentre alcuni potrebbero essere kilobyte o meno. L’allocazione di centinaia di megabyte che non sono necessari renderebbe il programma difficile da eseguire su alcuni computer mentre l’allocazione di poca memoria significherebbe che ci sono alcune immagini che non possiamo gestire.
Un buon approccio a questo problema è l’allocazione della memoria secondo necessità. Questo è chiamato Allocazione dinamica della memoria. Chiediamo semplicemente quanto ci serve mentre il programma è in esecuzione (piuttosto che in fase di compilazione), né più né meno. Nel nostro esempio, questo ci permetterebbe di modificare sia i file di immagine enormi che piccoli in modo efficiente ed efficace. C’è una certa complessità aggiunta dal momento che non è più la lingua che si occupa dei dettagli dell’allocazione, ma noi direttamente. Nel nostro esempio, se stiamo eseguendo su un computer di fascia inferiore, potrebbe non esserci abbastanza memoria per ospitare file di immagini di grandi dimensioni, quindi dobbiamo rilevare (e possibilmente fallire con grazia) in tali situazioni.
L’allocazione dinamica della memoria è una fonte principale di “perdite di memoria”, in cui i programmi allocano, utilizzano e vengono quindi eseguiti con un’area di memoria, ma non riescono a contrassegnarla come disponibile ancora una volta. Questi problemi possono essere difficili da rintracciare poiché a differenza di altri bug, le perdite non sono facilmente evidenti.
Alcuni linguaggi moderni hanno meccanismi integrati per cercare di prevenire perdite di memoria, noti come garbage collection. Questo sistema tiene traccia di quale allocazione viene utilizzata dove, quando è fuori portata. La garbage collection ha una leggera penalizzazione delle prestazioni, ma ora è comunemente considerata un progresso. Java e Python, ad esempio, hanno un garbage collector.