Lezioni: introduzione generale: differenze tra le versioni
Nessun oggetto della modifica |
Nessun oggetto della modifica |
||
| (131 versioni intermedie di uno stesso utente non sono mostrate) | |||
| Riga 1: | Riga 1: | ||
Gli elementi fondamentali e basilari di un calcolatore sono un microprocessore, per elaborare i dati, e la memoria, per immagazzinare i dati elaborati o da elaborare da parte del microprocessore. | Gli elementi fondamentali e basilari di un calcolatore sono un ''microprocessore'', per elaborare i dati, e la ''memoria'', per immagazzinare i dati elaborati o da elaborare da parte del microprocessore. | ||
=La Memoria= | =La Memoria= | ||
| Riga 5: | Riga 6: | ||
Dal punto di vista logico la memoria è una sorta di vettore di elementi individuati univocamente da un ''indice'' progressivo che ne rappresenta l'indirizzo. Tali elementi possono essere rappresentati plasticamente da celle di una griglia più grande, che è la memoria medesima. | Dal punto di vista logico la memoria è una sorta di vettore di elementi individuati univocamente da un ''indice'' progressivo che ne rappresenta l'indirizzo. Tali elementi possono essere rappresentati plasticamente da celle di una griglia più grande, che è la memoria medesima. | ||
=Codificazione dei dati in memoria: i dati elementari come stati di tensione elettrica= | =Codificazione dei dati in memoria: i dati elementari come stati di tensione elettrica= | ||
I dati in memoria vengono salvati attraverso stati di tensione elettrica, così distinti: | I dati in memoria vengono salvati attraverso stati di tensione elettrica, così distinti: | ||
* tensione alta: V<FONT Size=1>high</font> = | * tensione alta: V<FONT Size=1>high</font> = 5volt o 3,3volt | ||
* tensione bassa: V<FONT Size=1>low</font> = | * tensione bassa: V<FONT Size=1>low</font> = 0volt | ||
In tal senso gli stati di tensione elettrica, appena visti, possono essere considerati i dati di informazione più basilari ed elementari nella tecnologia digitale informatica. Pertanto i dati vengono codificati sempre mediante "''sequenze''" di valori di tensione V<FONT Size=1>high</font> o V<FONT Size=1>low</font>. | In tal senso gli stati di tensione elettrica, appena visti, possono essere considerati i dati di informazione più basilari ed elementari nella tecnologia digitale informatica. Pertanto i dati vengono codificati sempre mediante "''sequenze''" di valori di tensione V<FONT Size=1>high</font> o V<FONT Size=1>low</font>. | ||
<BR>Esempio: | <BR>Esempio: | ||
| Riga 15: | Riga 17: | ||
__⌈¯¯⌊__⌈¯¯¯¯¯⌊_____⌈¯¯⌊ | __⌈¯¯⌊__⌈¯¯¯¯¯⌊_____⌈¯¯⌊ | ||
0v 0v 0v 0v | 0v 0v 0v 0v | ||
Anche il processore (CPU), come la memoria, reagisce e opera in base alla combinazione degli impulsi elettrici ricevuti nell'unità di tempo. | |||
==Rappresentazione degli stati di tensione elettrica nel sistema binario== | ==Rappresentazione degli stati di tensione elettrica nel sistema binario== | ||
Affinché sia umanamente più comprensibile soprattutto in fase di | Affinché sia umanamente più comprensibile soprattutto in fase di programmazione di un codice sorgente, tali valori di tensione vengono per convenzione rappresentati dalle due cifre binarie '''0''' e '''1'''; e segnatamente lo stato di tensione elettrica V<FONT Size=1>low</font> (0v) è associato al numero binario 0, mentre lo stato V<FONT Size=1>high</font> (5v) è associato al numero binario 1. | ||
Ogni stato di tensione V<FONT Size=1>high</font> o V<FONT Size=1>low</font> è chiamato '''bit'''. Pertanto la CPU e la memoria lavorano tramite sequenze di ''bit'' aventi stato 1 oppure 0. | Ogni stato di tensione V<FONT Size=1>high</font> o V<FONT Size=1>low</font> è chiamato '''bit'''. Pertanto la CPU e la memoria lavorano tramite sequenze di ''bit'' aventi stato 1 oppure 0. | ||
Affinché la CPU possa effettuare le operazioni | Riprendendo dunque l'esempio precedente avremo: | ||
1 1 1 1 | |||
___⌈¯¯¯⌊___⌈¯¯¯¯¯¯¯⌊_______⌈¯¯¯⌊ | |||
0 0 0 0 | |||
Affinché la CPU possa effettuare le operazioni, capace di compiere <SUP>[[[#Note|nota 1]]]</sup>, deve ricevere gruppi di sequenze di ''bit'', che per essa abbiano ''significato''. Ogni gruppo di stati di tensione, ''bit'', avente per la CPU un ''significato'' operativo (ad esempio un comando), è formato da 8 ''bit''. La CPU infatti esegue solo ''istruzioni'': ogni sequenza di bit (stati di tensione V<FONT Size=1>high</font> o V<FONT Size=1>low</font>), che giunge alla CPU in qualità di ''istruzione'', produce nel microprocessore una elaborazione di tali dati e conseguenzialmente delle azioni, che hanno effetti esterni alla CPU medesima. | |||
Ugualmente anche ogni cella (''indirizzo'') di memoria potrà contenere, memorizzato, solo e sempre un insieme di 8 ''bit''. | Ugualmente anche ogni cella (''indirizzo'') di memoria potrà contenere, memorizzato, solo e sempre un insieme di 8 ''bit''. | ||
| Riga 31: | Riga 38: | ||
<FONT Color=blue size=3><B>01011001</b></font> | <FONT Color=blue size=3><B>01011001</b></font> | ||
<FONT Size=2>1 Byte</font> | <FONT Size=2>1 Byte</font> | ||
==Dalla rappresentazione binaria alla rappresentazione numerica== | ==Dalla rappresentazione binaria alla rappresentazione numerica== | ||
Per rendere ancor più comprensibile e semplificare la rappresentazione dei valori di tensione (per ora convertiti in rappresentazione binaria con bit posti a 0 o 1 a seconda della tensione elettrica rappresentata), si è convenzionalmente | Per rendere ancor più comprensibile e semplificare la rappresentazione dei valori di tensione (per ora convertiti in rappresentazione binaria con bit posti a 0 o 1 a seconda della tensione elettrica rappresentata), si è convenzionalmente associato un numero a ciascun bit in ragione della sua posizione all'interno del Byte: | ||
128 64 32 16 8 4 2 1 | 128 64 32 16 8 4 2 1 | ||
sommando | Da ciò si comprende facilmente anche perché il bit più a sinistra è definito il bit ''più significativo'': poiché ad esso è associato il valore massimo, ossia 128; mentre il bit più a destra è definito ''meno significativo'': poiché ad esso è associato il valore minimo, ossia 1. | ||
Quindi lo stato | <BR>Va fatto rilevare che sommando i valori, associati agli otto bit quando il loro stato è posto a 1, si ottiene '''255'''. Inoltre, va sottolineato che sulla base delle diverse combinazioni dello stato binario (0 e 1) che ogni bit può assumere, il Byte può assumere '''256''' valori diversi, come una sorta di gradiente partendo dallo 0 (ossia tutti i bit con stato a 0) sino a 255 (tutti i bit con stato a 1). | ||
<BR>Quindi lo stato complessivo di tutti i bit di ogni byte può essere rappresentato attraverso un numero intero dato dalla somma dei valori associati ai bit aventi il proprio stato a 1. | |||
<BR>Esempio: | <BR>Esempio: | ||
| '''0''' | '''1'''| '''0'''| '''1'''|''' | <TABLE> | ||
|128|64|32|16|8|4|2|1| | <TR><TD>|</td><TD align=right>'''0'''</td><TD>|</td><TD align=right>'''1'''</td><TD>|</td><TD align=right>'''0'''</td><TD>|</td><TD align=right>'''1'''</td><TD>|</td><TD>'''1'''</td><TD>|</td><TD>'''0'''</td><TD>|</td><TD align=center>'''0'''</td><TD>|</td><TD align=center>'''1'''</td><TD>|</td><TD style=color:transparent>......</td><TD>bit</td></tr> | ||
<TR><TD>|</td><TD>128</td><TD>|</td><TD>64</td><TD>|</td><TD>32</td><TD>|</td><TD>16</td><TD>|</td><TD>8</td><TD>|</td><TD>4</td><TD>|</td><TD align=center>2</td><TD>|</td><TD align=center>1</td><TD>|</td><TD style=color:transparent>......</td><TD>valori associati ai bit</td></tr> | |||
<TR><TD> </td><TD> </td><TD> </td><TD align=center>↓</td><TD> </td><TD> </td><TD> </td><TD align=center>↓</td><TD> </td><TD>↓</td><TD> </td><TD> </td><TD> </td><TD> </td><TD> </td><TD>↓</td></tr> | |||
Il Byte (insieme di 8 bit), come sopra rappresentato in binario, può dunque essere ancor più agevolmente e brevemente rappresentato, anche ai fini dell'effettuazione di una eventuale operazione aritmetica, dal valore intero | <TR><TD> </td><TD> </td><TD> </td><TD>64</td><TD> </td><TD align=center>+</td><TD> </td><TD>16</td><TD>+</td><TD>8</td><TD> </td><TD> </td><TD align=left>+</td><TD></td><TD></td><TD>1</td><TD></td><TD style=color:transparent>.</td><TD> = 97 valore rappresentativo del gruppo di 8 bit (Byte)</td></tr></table> | ||
<BR>Ciò significa che, se affermiamo che un certo Byte ha valore | Il Byte (insieme di 8 bit), come sopra nell'esempio rappresentato in binario, può dunque essere ancor più agevolmente e brevemente rappresentato, anche ai fini dell'effettuazione di una eventuale operazione aritmetica, dal valore intero 97. | ||
<BR>Ciò significa che, se affermiamo che un certo Byte ha valore 97 in rappresentazione numerica decimale, lo stato interno dei suoi ''bit'' è quello rappresentato nel precedente esempio, ossia: 01011001. Conseguentemente si disporrà così l'invio di una sequenza di valori di tensione elettrica: 0v_5v_0v_5v_5v_0v_0v_5v. | |||
In vero convenzionalmente, per rappresentare un valore assunto da un Byte, si è preferito usare il sistema ''esadecimale'', il quale può rappresentare numeri molto grandi mediante una quantità di cifre inferiore a quella richiesta dalla rappresentazione numerica ''decimale''. | In vero, convenzionalmente, per rappresentare un valore assunto da un Byte, si è preferito usare il sistema ''esadecimale'', il quale può rappresentare numeri molto grandi mediante una quantità di cifre inferiore a quella richiesta dalla rappresentazione numerica ''decimale''. | ||
I numeri, con cui il processore centrale è in grado di eseguire operazioni aritmetiche, sono rappresentati ovviamente da Byte di dati. Nei paragrafi precedenti abbiamo visto come - per semplificazione - ogni bit assume un valore numerico in base alla sua posizione nel byte, e abbiamo preso in considerazione un solo Byte, che però potrà - come sappiamo - rappresentare soltanto i numeri compresi nell'''ambitus'' da 0 a 255 (per un totale di 256 numeri rappresentabili). | =Dati monobyte e dati multibyte= | ||
I numeri, con cui il processore centrale è in grado di eseguire operazioni aritmetiche, sono rappresentati ovviamente da Byte di dati. Nei paragrafi precedenti abbiamo visto come - per semplificazione - ogni bit assume un valore numerico in base alla sua posizione nel byte, e abbiamo preso in considerazione un solo Byte, che però potrà - come sappiamo - rappresentare soltanto i numeri compresi nell'''ambitus'' da 0 a 255 (per un totale di 256 numeri ''rappresentabili''). | |||
<BR>Se però dobbiamo effettuare calcoli con numeri superiori al numero 255, come si farà ? | <BR>Se però dobbiamo effettuare calcoli con numeri superiori al numero 255, come si farà ? | ||
In questo caso si utilizzerà un Byte ulteriore, che si accoderà a sinistra del Byte avente i valori più bassi (cioè da 0 a 255), e assumerà i valori esponenziali di 2 successivi al valore 128: | |||
32768 16384 8192 4096 2048 1024 512 256 | |||
Pertanto il Byte, che rappresenta attraverso i suoi bit i numeri più elevati, sarà definito ''più significativo'', mentre il Byte, rappresentante i valori più bassi, sarà definito ''meno significativo''. | |||
<table> | |||
<tr><td bgcolor=lightgreen>Byte "più significativo"</td><td>|</td><td bgcolor=#F5DEB3>Byte "meno significativo"</td></tr> | |||
<tr><td bgcolor=lightgreen>32768 16384 8192 4096 2048 1024 512 256</td><td>|</td><td bgcolor=#F5DEB3>128 64 32 16 8 4 2 1</td></tr> | |||
</table> | |||
<BR>Come è facilmente comprensibile, l'uso di due Byte, nelle diverse combinazioni degli stati binari che possono assumere i loro 8 + 8 bit, sono capaci di rappresentare numeri che compresi nell'''ambitus'' da '''0''' (tutti i sedici bit posti a 0) fino a '''65535''' (tutti i i sedici bit posti a 1), per un totale di 65536 numeri ''rappresentabili''. <SUP>[[[#Note|nota 2]]]</sup> | |||
Quando un valore può essere rappresentato esclusivamente da una quantità di Byte superiore a uno, possiamo parlare di valori ''multibyte'', e per conseguenza di dati ''multibyte''. | |||
==Rappresentazione dei numeri in memoria, numero di Byte utilizzati e consumo della memoria== | |||
Come è comprensibile, non è indifferente la circostanza di dover utilizzare uno o più Byte per rappresentare un valore numerico. Infatti l'utilizzo di un Byte significa dover ''occupare'' in memoria una cella (indirizzo). | |||
La questione si comprende meglio se si immagina di dover memorizzare un valore numerico inferiore a 256. Come sappiamo basterà usare (ossia: occupare) una sola cella di memoria, ma - volendo nulla ci vieta di richiedere al sistema di occupare due o più celle per poi - agli effetti della rappresentazione del numero da memorizzare - utilizzarne solo una. | |||
<BR>Facciamo l'esempio con l'occupazione di due Byte di memoria per memorizzare un numero rappresentabile semplicemente con un solo Byte: | |||
⸐⸏⸏⸏⸏⸏________⸏⸏⸏⸏⸑ | |||
00000000 100101010 | |||
<FONT Size=1>Byte più sig.</font> <FONT Size=1>Byte meno sig.</font> | |||
E' ampiamente evidente lo spreco di risorsa della memoria: a cosa può mai servire lì un secondo Byte (quello ''più significativo'') con i bit posti tutti a 0 ? Si immagini la richiesta di occupazione/utilizzo di 4 Byte per un numero rappresentabile semplicemente con 1 Byte, quanto spreco di memoria comporterebbe ! | |||
==Ordine dei Byte in memoria== | |||
Questi dati multibyte utilizzabili dal processore, per eseguire operazioni, ovviamente sono anche immagazzinabili in memoria, per poter essere eventualmente usati nel prosieguo del programma. | |||
<BR>Si è già definito in precedenza il concetto di Byte ''più significativo'' e di Byte ''meno significativo'', sarà possibile sia da parte del sistema che da parte del programmatore porre questi due Byte nel loro ordine ''naturale'', ad esempio considerando il valore (in numerazione decimale) 123456 (in esadecimale: &h01E240 dovendosi usare ben tre Byte, per poter essere adeguatamente rappresentato): | |||
<FONT Color=red>01</font> E2 <FONT Color=blue>40</font> <FONT Size=1>(come vedete, più agevolmente rappresentabile in numerazione esadecimale)</font> | |||
laddove il primo Byte, quello colorato in rosso, è il Byte ''più significativo'' (conferisce al numero i valori più elevati dei bit costituenti l'intero numero), mentre quello colorato in blu è il Byte ''meno significativo''. | |||
In tal caso, poiché appunto alla sinistra dell'intero velore, rappresentato dai tre Byte in numerazione esadecimale, è posto il Byte ''più significativo'', l'ordine di memorizzazione è chiamato: " '''''Big-Endian''''' ". | |||
<BR>Al contrario una memorizzazione con i Byte invertiti: | |||
<FONT Color=blue>40</font> E2 <FONT Color=red>01</font> | |||
ove il primo Byte (più a sinistra del gruppo) è quello ''meno significativo'', mentre il Byte più a destra ora è quello ''più significativo'', segue l'ordine chiamato: " '''''Little-Endian''''' ". | |||
L'ordine, in cui i singoli Byte di un dato ''multibyte'' sono memorizzati, è chiamato " ''Endianess'' ". | |||
Ai fini della gestibilità e della velocità di elaborazione l'ordine dei Byte è indifferente per la CPU. | |||
=Allocazione automatica a dimensione fissa e allocazione arbitraria a dimensione mobile della memoria= | |||
Si è già fatto cenno alla circostanza per cui la memoria può essere considerata visivamente come una sorta di griglia, composta di tante unità di memorizzazione, le celle di questa griglia, ognuna delle quali individuata da un "indirizzo" di memoria, e capace di ''ospitare'', memorizzare un solo Byte (quindi solo 8 bit). Pertanto, se si deve memorizzare un valore, rappresentabile necessariamente da 2 Byte, bisognerà ''occupare'' (utilizzare) in sequenza 2 celle (indirizzi) di memoria. In tal caso si dice che saranno occupati 2 Byte di memoria. | |||
Il sistema non scriverà i dati da memorizzare in qualsiasi cella (indirizzo) di memoria, poiché si rischierebbe di sovrascrivere dati, precedentemente memorizzati, molto importanti. Esso si accerterà che tali celle (indirizzi) siano ''disponibili'' ad ''accogliere'' i dati da scrivere, quindi a memorizzare nuovi valori Byte. | |||
<BR>Per garantire la persistenza del tempo dei dati memorizzati nelle celle di memoria, è necessario impedire - ovviamente - che essi possano essere ''sovrascritti'' successivamente da altri dati senza che sia stabilito e consentito dal codice sorgente del programma. Il sistema, dunque, "''riserva''", ovvero "''alloca''" <SUP>[[[#Note|nota 3]]]</sup>, in modalità sequenziale le celle (indirizzi) di memoria in quantità necessaria, oppure arbitrariamente ed esplicitamente imposta dal programma, per la scrittura dei Byte che rappresentano il valore numerico da memorizzare. | |||
<BR>Come si è lasciato intendere prima, tali celle potranno essere sovrascritte durante il funzionamento del programma solo se consentito dal suo codice sorgente. | |||
L'allocazione di una determinata quantità di celle (indirizzi o anche dette Byte) di memoria può essere in grandi linee suddivisa in due modalità: | |||
* allocazione ''automatica'' (non c'è bisogno di creare la Classe per potervi accedere) a dimensione fissa; | |||
* allocazione ''arbitraria'' a dimensione mobile. | |||
==Deallocazione di un'area di memoria precedentemente allocata== | |||
Una quantità di celle precedentemente allocate (ossi garantite contro il rischio di sovrascrittura di nuovi dati) può sempre essere riutilizzata, come in una sorta di ''riciclaggio della memoria''. Questo significa che l'area (le celle, gli indirizzi) di memoria precedentemente riservata deve essere ''dichiarata'' non più riservata, libera. Per fare ciò si deve procedere alla deallocazione della porzione memoria precedentemente allocata. | |||
<BR>L'area di memoria, riservata in precedenza, viene così ''liberata'' e diventa nuovamente scrivibile, utilizzabile. | |||
==Allocazione automatica a dimensione fissa: la "Variabile" e la "Costante"== | |||
I linguaggi di programmazione sulla base delle caratteristiche e delle impostazioni hardware e del sistema operativo, forniscono una tipologia di quantità "''fisse''" (non modificabile nel suo numero dal programmatore) e "''prestabilite''" di memoria allocata, nelle quali è possibile dunque scrivere ambiti di valori prestabiliti. | |||
===Persistenza del valore memorizzato in una locazione di memoria=== | |||
I valori immagazzinati in locazioni (ossia in una o più celle) di memoria possono essere: | |||
<BR>- modificabili, ossia le celle che ne contengono i dati-Byte possono essere sovrascrivibili con altri valori, rappresentabili con il medesimo numero di Byte; | |||
<BR>- non modificabili, e pertanto le celle non sono sovrascrivibili, fin tanto che dura il programma. | |||
Nel primo caso di ''allocazione'' si parla più specificatamente di "''[[Le_Variabili|Variabile]]''", nel secondo caso si parla di "''[[Le_Costanti|Costante'']]". | |||
Le quantità prestabilite e fisse di memoria allocabile sono, dunque, chiamate "''[[Le_Variabili|Variabili]]''", se il valore contenuto è modificabile (le "variabili", hanno lo scopo di contenere dati mutabili nel tempo), oppure , se il valore <SPAN Style="text-decoration:underline">non</span> è modificabile, "''[[Le_Costanti|Costanti'']]". | |||
<BR>Una ''[[Le_Variabili|Variabile]]'' rappresenta un'area, una porzione, ossia un numero di celle prestabilito e fisso, di memoria capace di immagazzinare un valore. Essa si riferisce e rappresenta l'indirizzo della prima cella di quell'area di memoria, ove possono essere memorizzati i Byte costituenti il valore da salvare, e segnatamente nel caso di dati multiByte l'indirizzo della cella di memoria del Byte più a sinistra, ossia quello del Byte ''più significativo''. | |||
<BR>A livello di codice ogni ''Variabile'' è distinta dalle altre ''[[Le_Variabili|Variabili]]'' mediante il proprio ''Identificatore'', che è in sostanza una sequenza alfanumerica che può contenere anche il simbolo del trattino in basso ( _ ). Una ''[[Le_Variabili|Variabile]]'', dunque, è un indirizzo ''simbolico'' della memoria, | |||
Una [[Le_Variabili|Variabile]] rappresenta l'indirizzo di memoria della cella di un'area di memoria ''riservata'' <SPAN Style="text-decoration:underline">automaticamente</span> dal sistema in base alla tipologia prevista. Tale [[Le_Variabili|Variabile]] su richiesta del codice del programma restituisce <SPAN Style="text-decoration:underline">immediatamente</span> il valore in essa contenuto, ossia memorizzato nell'area di memoria riservata alla quale la Variabile si riferisce, ''punta''. | |||
<BR>Con riguardo a quest'ultimo concetto la ''[[Le_Variabili|Variabile]]'', per poter scrivere o leggere i dati memorizzati che rappresentano il valore, punta in scrittura e in lettura alla cella del dato monoByte, e - in caso di dato multiByte - alla <SPAN Style="text-decoration:underline">prima</span> cella, ossia al Byte più a sinistra del gruppo di Byte rappresentanti il predetto valore: | |||
⁔ ⁔ | |||
'''01''' E2 40 | |||
<FONT Size=5>⇡</font> | |||
<FONT Size=2>variabile</font> | |||
In altri termini la ''Variabile'' implicitamente è legata anche alle seguenti informazioni: | |||
<BR>1) <SPAN Style="text-decoration:underline">da quale</span> indirizzo di memoria si deve cominciare a scrivere o a leggere in modo sequenziale un valore; | |||
<BR>2) <SPAN Style="text-decoration:underline">quanti</span> Byte (celle) di memoria devono essere utilizzati per scrivere o per leggere in modo sequenziale un valore. | |||
Quando una [[Le_Variabili|Variabile]] è ''automatica'': | |||
<BR>1) la quantità di Byte scrivibile alla quale essa ''punta'', è <U>prestabilita</u> dal linguaggio di programmazione (in base al sistema operativo); | |||
<BR>2) all'allocazione della quantità di memoria prevista vi provvede ''automaticamente'' il sistema; | |||
<BR>3) la deallocazione della quantità di celle precedentemente riservate avviene automaticamente da parte del sistema. <SUP>[[[#Note|nota 4]]]</sup> | |||
===Tipologia in Gambas della quantità di memoria allocata automatica a dimensione fissa=== | |||
La quantità <U>prestabilita</u> dal sistema e fissa delle celle di memoria scrivibile, dunque la tipologia di ''variabili'' fornite dal linguaggio Gambas può essere riscontrata nell'apposita pagina web del sito della Wiki ufficiale di Gambas: [http://gambaswiki.org/wiki/lang/type Native datatypes] . | |||
Quando si dichiara una ''Variabile'' oppure una ''Costante'', non si fa altro dunque che richiedere al sistema di allocare una quantità di celle di memoria secondo il tipo predefinito, scelto dal programmatore tra quelli forniti dal linguaggio di programmazione utilizzato. Tale area di memoria riservata automaticamente dal sistema è univocamente individuata e richiamabile nel codice sorgente attraverso il proprio ''Identificatore'' alfanumerico. | |||
===Attributi della Variabile=== | |||
Una ''Variabile'' (ma anche una ''Costante'') si definisce secondo tre attributi: | |||
* un ''identificatore'', ossia il nome della variabile definito dal programmatore; | |||
* un ''indirizzo'' di memoria, ove ha inizio il valore o l'insieme di valori memorizzati che costituisce il dato salvato; | |||
* un ''tipo'' che definisce la quantità di memoria occupata, utilizzata per memorizzare il dato nella variabile. | |||
==Allocazione arbitraria a dimensione mobile (dinamica)== | |||
I linguaggi di programmazione, come il C, il C++ ed altri, ma anche Gambas, forniscono al programmatore una grande risorsa: consentono di allocare un numero arbitrario di celle di memoria. | |||
<BR>Possiamo dire, peraltro, che essi, oltre a mettere a disposizione del programmatore una serie di allocazioni automatiche di quantità predefinite e immodificabili (anche dette: ''[[Le_Variabili|Variabili]]'') di celle di memoria, forniscono pure la possibilità di riservare un qualsiasi numero a scelta del programmatore (per questo arbitrario) di celle di memoria, adoperando specifiche funzioni native del linguaggio utilizzato. | |||
<BR>Poiché la quantità di celle/Byte di memoria allocate è del tutto arbitraria, cioè stabilita dal programmatore in sede di codice sorgente del programma, il sistema non potrà fare altro che allocare il numero di celle stabilito dal programmatore, e restituire il numero dell'indirizzo di memoria del Byte allocato, se trattasi di dato monoByte, ovvero del Byte di memoria più a sinistra, se trattasi di dato multiByte. | |||
<BR>Questa circostanza è facilmente comprensibile: se non avessimo a disposizione l'indirizzo di memoria , ove il dato mono o multiByte è stato memorizzato, non potremmo mai rintracciarlo, ritrovarlo, e quindi non potremmo mai più scriverci, leggerci, né deallocarlo. | |||
<BR>Va aggiunto che la quantità di memoria così allocata in modo arbitrario, è dinamica, ossia può essere variata utilizzando una specifica funzione di riallocazione della quantità di celle di memoria da utilizzare per la memorizzazione dei dati-Byte. La quantità - precedentemente stabilita in modo arbitrario - di celle/Byte di memoria, da riservare per la memorizzazione dei dati, può dunque essere modificata e reimpostata ''a volontà'' e più volte. | |||
I linguaggi forniscono una speciale ''[[Le_Variabili|Variabile]]'' preposta a contenere il numero che rappresenta l'<SPAN Style="text-decoration:underline">indirizzo</span> di memoria del Byte o dei Byte di memoria arbitrariamente allocati dal programmatore <SUP>[[[#Note|nota 5]]]</sup>. Si dice che questa speciale [[Le_Variabili|Variabile]] semplicemente "''punta''" (cioè indica, si riferisce) all'indirizzo di memoria della cella/Byte, se trattasi di dato monoByte, ovvero della cella/Byte, se trattasi di dati multiByte, più a sinistra che rappresenta il valore memorizzato. | |||
<BR>Pertanto questa speciale [[Le_Variabili|Variabile]], che ci dice da quale indirizzo di memoria cominciare a scrivere o a leggere, viene chiamata "''Puntatore''", ed essa stessa è nativa del linguaggio di programmazione utilizzato (facendo così parte della tipologia delle [[Le_Variabili|Variabili]] a quantità di celle allocabili predefinita) rappresenta l'allocazione automatica, predefinita e fissa di una quantità di memoria adeguata per contenere appunto il numero di un indirizzo di memoria. | |||
<BR>Ovviamente per sapere quanti Byte deve poter scrivere o leggere, il sistema fa riferimento al numero impostato nella specifica funzione in sede di allocazione dell'area di memoria in questione, e alla quale il ''Puntatore'' punta (cioè della quale il Puntatore possiede il numero dell'indirizzo di memoria dell'unico Byte oppure del primo Byte più a sinistra). | |||
<BR>Nel codice per poter accedere al valore dell'area di memoria puntata dalla variabile di tipo ''Puntatore'', quest'ultima deve essere "''dereferenziata''". | |||
====Deallocazione di un'area allocata arbitrariamente==== | |||
Poiché una quantità di memoria allocata arbitrariamente non viene deallocata automaticamente dal sistema, a tale compito deve provvedere il programmatore all'interno del codice con un'apposita funzione prevista dal linguaggio di programmazione utilizzato. | |||
Come ormai è noto, la liberazione dell'area di memoria, precedentemente allocata, la restituisce alla sua originaria disponibilità di essere nuovamente riallocata da una diversa risorsa per diverse finalità. | |||
---- | |||
=Note= | |||
[1] La CPU può effettuare soltanto operazioni in aritmetica binaria: somma e differenza, scorrimento (''shift'') dei bit, operazioni logiche. | |||
[2] Poiché in Gambas attualmente i tipi di dati superiori al "Byte" supportano sia numeri positivi che numeri negativi, una metà dell'<I>ambitus</i> di rappresentabilità dei valori è dedicata a quelli positivi e l'altra metà è usata per rappresentare i valori negativi. Pertanto il tipo di dato con risoluzione a 16-bit ([http://gambaswiki.org/wiki/lang/type/short Short]) è capace di rappresentare numeri da -32.768 fino +32.767. | |||
[3] La memoria deve essere ''riservata'' prima di essere ''impegnata''. | |||
[4] Il concetto di "variabile automatica" è particolarmente legato alla "''visibilità''" della variabile medesima: una variabile dichiarata all'interno di una routine cessa di esistere ''automaticamente'', quando il processo esce da quella routine ove la variabile è stata dichiarata. Pertanto una variabile "''automatica''" per definizione è la variabile "''[[#Visibilit.C3.A0_all.27interno_della_Classe_e_del_Modulo:_.22Globale.22_e_.22Locale.22|locale]]''". | |||
[5] Va precisato, però, che in vari linguaggi di programmazione, come in Gambas, la variabile di tipo ''Puntatore'' può contenere anche l'indirizzo di memoria di una variabile nativa automatica, di cui alla tipologia prevista dal linguaggio di programmazione usato (non escluso l'indirizzo di memoria di un'altra variabile di tipo ''Puntatore''). In questi casi - come è ben comprensibile - l'area di memoria è già allocata all'atto dell'uso della variabile nativa, predefinita e fissa, quindi allocata automaticamente. Il ''Puntatore'' semplicemente e solo conterrà il numero dell'indirizzo di tale variabile nativa. | |||
Versione attuale delle 08:01, 22 ago 2025
Gli elementi fondamentali e basilari di un calcolatore sono un microprocessore, per elaborare i dati, e la memoria, per immagazzinare i dati elaborati o da elaborare da parte del microprocessore.
La Memoria
La Memoria è il supporto che consente di conservare dati, informazioni nel tempo.
Dal punto di vista logico la memoria è una sorta di vettore di elementi individuati univocamente da un indice progressivo che ne rappresenta l'indirizzo. Tali elementi possono essere rappresentati plasticamente da celle di una griglia più grande, che è la memoria medesima.
Codificazione dei dati in memoria: i dati elementari come stati di tensione elettrica
I dati in memoria vengono salvati attraverso stati di tensione elettrica, così distinti:
- tensione alta: Vhigh = 5volt o 3,3volt
- tensione bassa: Vlow = 0volt
In tal senso gli stati di tensione elettrica, appena visti, possono essere considerati i dati di informazione più basilari ed elementari nella tecnologia digitale informatica. Pertanto i dati vengono codificati sempre mediante "sequenze" di valori di tensione Vhigh o Vlow.
Esempio:
5v 5v 5v 5v __⌈¯¯⌊__⌈¯¯¯¯¯⌊_____⌈¯¯⌊ 0v 0v 0v 0v
Anche il processore (CPU), come la memoria, reagisce e opera in base alla combinazione degli impulsi elettrici ricevuti nell'unità di tempo.
Rappresentazione degli stati di tensione elettrica nel sistema binario
Affinché sia umanamente più comprensibile soprattutto in fase di programmazione di un codice sorgente, tali valori di tensione vengono per convenzione rappresentati dalle due cifre binarie 0 e 1; e segnatamente lo stato di tensione elettrica Vlow (0v) è associato al numero binario 0, mentre lo stato Vhigh (5v) è associato al numero binario 1.
Ogni stato di tensione Vhigh o Vlow è chiamato bit. Pertanto la CPU e la memoria lavorano tramite sequenze di bit aventi stato 1 oppure 0.
Riprendendo dunque l'esempio precedente avremo:
1 1 1 1 ___⌈¯¯¯⌊___⌈¯¯¯¯¯¯¯⌊_______⌈¯¯¯⌊ 0 0 0 0
Affinché la CPU possa effettuare le operazioni, capace di compiere [nota 1], deve ricevere gruppi di sequenze di bit, che per essa abbiano significato. Ogni gruppo di stati di tensione, bit, avente per la CPU un significato operativo (ad esempio un comando), è formato da 8 bit. La CPU infatti esegue solo istruzioni: ogni sequenza di bit (stati di tensione Vhigh o Vlow), che giunge alla CPU in qualità di istruzione, produce nel microprocessore una elaborazione di tali dati e conseguenzialmente delle azioni, che hanno effetti esterni alla CPU medesima.
Ugualmente anche ogni cella (indirizzo) di memoria potrà contenere, memorizzato, solo e sempre un insieme di 8 bit.
Ogni gruppo di 8 bit è chiamato Byte.
Riprendendo l'esempio, sopra esposto, di una sequenza di valori di tensioni elettriche, possiamo così rappresentarla in binario (sequenza di bit aventi stato 0 oppure stato 1):
8 bit 01011001 1 Byte
Dalla rappresentazione binaria alla rappresentazione numerica
Per rendere ancor più comprensibile e semplificare la rappresentazione dei valori di tensione (per ora convertiti in rappresentazione binaria con bit posti a 0 o 1 a seconda della tensione elettrica rappresentata), si è convenzionalmente associato un numero a ciascun bit in ragione della sua posizione all'interno del Byte:
128 64 32 16 8 4 2 1
Da ciò si comprende facilmente anche perché il bit più a sinistra è definito il bit più significativo: poiché ad esso è associato il valore massimo, ossia 128; mentre il bit più a destra è definito meno significativo: poiché ad esso è associato il valore minimo, ossia 1.
Va fatto rilevare che sommando i valori, associati agli otto bit quando il loro stato è posto a 1, si ottiene 255. Inoltre, va sottolineato che sulla base delle diverse combinazioni dello stato binario (0 e 1) che ogni bit può assumere, il Byte può assumere 256 valori diversi, come una sorta di gradiente partendo dallo 0 (ossia tutti i bit con stato a 0) sino a 255 (tutti i bit con stato a 1).
Quindi lo stato complessivo di tutti i bit di ogni byte può essere rappresentato attraverso un numero intero dato dalla somma dei valori associati ai bit aventi il proprio stato a 1.
Esempio:
| | | 0 | | | 1 | | | 0 | | | 1 | | | 1 | | | 0 | | | 0 | | | 1 | | | ...... | bit |
| | | 128 | | | 64 | | | 32 | | | 16 | | | 8 | | | 4 | | | 2 | | | 1 | | | ...... | valori associati ai bit |
| ↓ | ↓ | ↓ | ↓ | |||||||||||||||
| 64 | + | 16 | + | 8 | + | 1 | . | = 97 valore rappresentativo del gruppo di 8 bit (Byte) |
Il Byte (insieme di 8 bit), come sopra nell'esempio rappresentato in binario, può dunque essere ancor più agevolmente e brevemente rappresentato, anche ai fini dell'effettuazione di una eventuale operazione aritmetica, dal valore intero 97.
Ciò significa che, se affermiamo che un certo Byte ha valore 97 in rappresentazione numerica decimale, lo stato interno dei suoi bit è quello rappresentato nel precedente esempio, ossia: 01011001. Conseguentemente si disporrà così l'invio di una sequenza di valori di tensione elettrica: 0v_5v_0v_5v_5v_0v_0v_5v.
In vero, convenzionalmente, per rappresentare un valore assunto da un Byte, si è preferito usare il sistema esadecimale, il quale può rappresentare numeri molto grandi mediante una quantità di cifre inferiore a quella richiesta dalla rappresentazione numerica decimale.
Dati monobyte e dati multibyte
I numeri, con cui il processore centrale è in grado di eseguire operazioni aritmetiche, sono rappresentati ovviamente da Byte di dati. Nei paragrafi precedenti abbiamo visto come - per semplificazione - ogni bit assume un valore numerico in base alla sua posizione nel byte, e abbiamo preso in considerazione un solo Byte, che però potrà - come sappiamo - rappresentare soltanto i numeri compresi nell'ambitus da 0 a 255 (per un totale di 256 numeri rappresentabili).
Se però dobbiamo effettuare calcoli con numeri superiori al numero 255, come si farà ?
In questo caso si utilizzerà un Byte ulteriore, che si accoderà a sinistra del Byte avente i valori più bassi (cioè da 0 a 255), e assumerà i valori esponenziali di 2 successivi al valore 128:
32768 16384 8192 4096 2048 1024 512 256
Pertanto il Byte, che rappresenta attraverso i suoi bit i numeri più elevati, sarà definito più significativo, mentre il Byte, rappresentante i valori più bassi, sarà definito meno significativo.
| Byte "più significativo" | | | Byte "meno significativo" |
| 32768 16384 8192 4096 2048 1024 512 256 | | | 128 64 32 16 8 4 2 1 |
Come è facilmente comprensibile, l'uso di due Byte, nelle diverse combinazioni degli stati binari che possono assumere i loro 8 + 8 bit, sono capaci di rappresentare numeri che compresi nell'ambitus da 0 (tutti i sedici bit posti a 0) fino a 65535 (tutti i i sedici bit posti a 1), per un totale di 65536 numeri rappresentabili. [nota 2]
Quando un valore può essere rappresentato esclusivamente da una quantità di Byte superiore a uno, possiamo parlare di valori multibyte, e per conseguenza di dati multibyte.
Rappresentazione dei numeri in memoria, numero di Byte utilizzati e consumo della memoria
Come è comprensibile, non è indifferente la circostanza di dover utilizzare uno o più Byte per rappresentare un valore numerico. Infatti l'utilizzo di un Byte significa dover occupare in memoria una cella (indirizzo).
La questione si comprende meglio se si immagina di dover memorizzare un valore numerico inferiore a 256. Come sappiamo basterà usare (ossia: occupare) una sola cella di memoria, ma - volendo nulla ci vieta di richiedere al sistema di occupare due o più celle per poi - agli effetti della rappresentazione del numero da memorizzare - utilizzarne solo una.
Facciamo l'esempio con l'occupazione di due Byte di memoria per memorizzare un numero rappresentabile semplicemente con un solo Byte:
⸐⸏⸏⸏⸏⸏________⸏⸏⸏⸏⸑ 00000000 100101010 Byte più sig. Byte meno sig.
E' ampiamente evidente lo spreco di risorsa della memoria: a cosa può mai servire lì un secondo Byte (quello più significativo) con i bit posti tutti a 0 ? Si immagini la richiesta di occupazione/utilizzo di 4 Byte per un numero rappresentabile semplicemente con 1 Byte, quanto spreco di memoria comporterebbe !
Ordine dei Byte in memoria
Questi dati multibyte utilizzabili dal processore, per eseguire operazioni, ovviamente sono anche immagazzinabili in memoria, per poter essere eventualmente usati nel prosieguo del programma.
Si è già definito in precedenza il concetto di Byte più significativo e di Byte meno significativo, sarà possibile sia da parte del sistema che da parte del programmatore porre questi due Byte nel loro ordine naturale, ad esempio considerando il valore (in numerazione decimale) 123456 (in esadecimale: &h01E240 dovendosi usare ben tre Byte, per poter essere adeguatamente rappresentato):
01 E2 40 (come vedete, più agevolmente rappresentabile in numerazione esadecimale)
laddove il primo Byte, quello colorato in rosso, è il Byte più significativo (conferisce al numero i valori più elevati dei bit costituenti l'intero numero), mentre quello colorato in blu è il Byte meno significativo.
In tal caso, poiché appunto alla sinistra dell'intero velore, rappresentato dai tre Byte in numerazione esadecimale, è posto il Byte più significativo, l'ordine di memorizzazione è chiamato: " Big-Endian ".
Al contrario una memorizzazione con i Byte invertiti:
40 E2 01
ove il primo Byte (più a sinistra del gruppo) è quello meno significativo, mentre il Byte più a destra ora è quello più significativo, segue l'ordine chiamato: " Little-Endian ".
L'ordine, in cui i singoli Byte di un dato multibyte sono memorizzati, è chiamato " Endianess ".
Ai fini della gestibilità e della velocità di elaborazione l'ordine dei Byte è indifferente per la CPU.
Allocazione automatica a dimensione fissa e allocazione arbitraria a dimensione mobile della memoria
Si è già fatto cenno alla circostanza per cui la memoria può essere considerata visivamente come una sorta di griglia, composta di tante unità di memorizzazione, le celle di questa griglia, ognuna delle quali individuata da un "indirizzo" di memoria, e capace di ospitare, memorizzare un solo Byte (quindi solo 8 bit). Pertanto, se si deve memorizzare un valore, rappresentabile necessariamente da 2 Byte, bisognerà occupare (utilizzare) in sequenza 2 celle (indirizzi) di memoria. In tal caso si dice che saranno occupati 2 Byte di memoria.
Il sistema non scriverà i dati da memorizzare in qualsiasi cella (indirizzo) di memoria, poiché si rischierebbe di sovrascrivere dati, precedentemente memorizzati, molto importanti. Esso si accerterà che tali celle (indirizzi) siano disponibili ad accogliere i dati da scrivere, quindi a memorizzare nuovi valori Byte.
Per garantire la persistenza del tempo dei dati memorizzati nelle celle di memoria, è necessario impedire - ovviamente - che essi possano essere sovrascritti successivamente da altri dati senza che sia stabilito e consentito dal codice sorgente del programma. Il sistema, dunque, "riserva", ovvero "alloca" [nota 3], in modalità sequenziale le celle (indirizzi) di memoria in quantità necessaria, oppure arbitrariamente ed esplicitamente imposta dal programma, per la scrittura dei Byte che rappresentano il valore numerico da memorizzare.
Come si è lasciato intendere prima, tali celle potranno essere sovrascritte durante il funzionamento del programma solo se consentito dal suo codice sorgente.
L'allocazione di una determinata quantità di celle (indirizzi o anche dette Byte) di memoria può essere in grandi linee suddivisa in due modalità:
- allocazione automatica (non c'è bisogno di creare la Classe per potervi accedere) a dimensione fissa;
- allocazione arbitraria a dimensione mobile.
Deallocazione di un'area di memoria precedentemente allocata
Una quantità di celle precedentemente allocate (ossi garantite contro il rischio di sovrascrittura di nuovi dati) può sempre essere riutilizzata, come in una sorta di riciclaggio della memoria. Questo significa che l'area (le celle, gli indirizzi) di memoria precedentemente riservata deve essere dichiarata non più riservata, libera. Per fare ciò si deve procedere alla deallocazione della porzione memoria precedentemente allocata.
L'area di memoria, riservata in precedenza, viene così liberata e diventa nuovamente scrivibile, utilizzabile.
Allocazione automatica a dimensione fissa: la "Variabile" e la "Costante"
I linguaggi di programmazione sulla base delle caratteristiche e delle impostazioni hardware e del sistema operativo, forniscono una tipologia di quantità "fisse" (non modificabile nel suo numero dal programmatore) e "prestabilite" di memoria allocata, nelle quali è possibile dunque scrivere ambiti di valori prestabiliti.
Persistenza del valore memorizzato in una locazione di memoria
I valori immagazzinati in locazioni (ossia in una o più celle) di memoria possono essere:
- modificabili, ossia le celle che ne contengono i dati-Byte possono essere sovrascrivibili con altri valori, rappresentabili con il medesimo numero di Byte;
- non modificabili, e pertanto le celle non sono sovrascrivibili, fin tanto che dura il programma.
Nel primo caso di allocazione si parla più specificatamente di "Variabile", nel secondo caso si parla di "Costante".
Le quantità prestabilite e fisse di memoria allocabile sono, dunque, chiamate "Variabili", se il valore contenuto è modificabile (le "variabili", hanno lo scopo di contenere dati mutabili nel tempo), oppure , se il valore non è modificabile, "Costanti".
Una Variabile rappresenta un'area, una porzione, ossia un numero di celle prestabilito e fisso, di memoria capace di immagazzinare un valore. Essa si riferisce e rappresenta l'indirizzo della prima cella di quell'area di memoria, ove possono essere memorizzati i Byte costituenti il valore da salvare, e segnatamente nel caso di dati multiByte l'indirizzo della cella di memoria del Byte più a sinistra, ossia quello del Byte più significativo.
A livello di codice ogni Variabile è distinta dalle altre Variabili mediante il proprio Identificatore, che è in sostanza una sequenza alfanumerica che può contenere anche il simbolo del trattino in basso ( _ ). Una Variabile, dunque, è un indirizzo simbolico della memoria,
Una Variabile rappresenta l'indirizzo di memoria della cella di un'area di memoria riservata automaticamente dal sistema in base alla tipologia prevista. Tale Variabile su richiesta del codice del programma restituisce immediatamente il valore in essa contenuto, ossia memorizzato nell'area di memoria riservata alla quale la Variabile si riferisce, punta.
Con riguardo a quest'ultimo concetto la Variabile, per poter scrivere o leggere i dati memorizzati che rappresentano il valore, punta in scrittura e in lettura alla cella del dato monoByte, e - in caso di dato multiByte - alla prima cella, ossia al Byte più a sinistra del gruppo di Byte rappresentanti il predetto valore:
⁔ ⁔ 01 E2 40 ⇡ variabile
In altri termini la Variabile implicitamente è legata anche alle seguenti informazioni:
1) da quale indirizzo di memoria si deve cominciare a scrivere o a leggere in modo sequenziale un valore;
2) quanti Byte (celle) di memoria devono essere utilizzati per scrivere o per leggere in modo sequenziale un valore.
Quando una Variabile è automatica:
1) la quantità di Byte scrivibile alla quale essa punta, è prestabilita dal linguaggio di programmazione (in base al sistema operativo);
2) all'allocazione della quantità di memoria prevista vi provvede automaticamente il sistema;
3) la deallocazione della quantità di celle precedentemente riservate avviene automaticamente da parte del sistema. [nota 4]
Tipologia in Gambas della quantità di memoria allocata automatica a dimensione fissa
La quantità prestabilita dal sistema e fissa delle celle di memoria scrivibile, dunque la tipologia di variabili fornite dal linguaggio Gambas può essere riscontrata nell'apposita pagina web del sito della Wiki ufficiale di Gambas: Native datatypes .
Quando si dichiara una Variabile oppure una Costante, non si fa altro dunque che richiedere al sistema di allocare una quantità di celle di memoria secondo il tipo predefinito, scelto dal programmatore tra quelli forniti dal linguaggio di programmazione utilizzato. Tale area di memoria riservata automaticamente dal sistema è univocamente individuata e richiamabile nel codice sorgente attraverso il proprio Identificatore alfanumerico.
Attributi della Variabile
Una Variabile (ma anche una Costante) si definisce secondo tre attributi:
- un identificatore, ossia il nome della variabile definito dal programmatore;
- un indirizzo di memoria, ove ha inizio il valore o l'insieme di valori memorizzati che costituisce il dato salvato;
- un tipo che definisce la quantità di memoria occupata, utilizzata per memorizzare il dato nella variabile.
Allocazione arbitraria a dimensione mobile (dinamica)
I linguaggi di programmazione, come il C, il C++ ed altri, ma anche Gambas, forniscono al programmatore una grande risorsa: consentono di allocare un numero arbitrario di celle di memoria.
Possiamo dire, peraltro, che essi, oltre a mettere a disposizione del programmatore una serie di allocazioni automatiche di quantità predefinite e immodificabili (anche dette: Variabili) di celle di memoria, forniscono pure la possibilità di riservare un qualsiasi numero a scelta del programmatore (per questo arbitrario) di celle di memoria, adoperando specifiche funzioni native del linguaggio utilizzato.
Poiché la quantità di celle/Byte di memoria allocate è del tutto arbitraria, cioè stabilita dal programmatore in sede di codice sorgente del programma, il sistema non potrà fare altro che allocare il numero di celle stabilito dal programmatore, e restituire il numero dell'indirizzo di memoria del Byte allocato, se trattasi di dato monoByte, ovvero del Byte di memoria più a sinistra, se trattasi di dato multiByte.
Questa circostanza è facilmente comprensibile: se non avessimo a disposizione l'indirizzo di memoria , ove il dato mono o multiByte è stato memorizzato, non potremmo mai rintracciarlo, ritrovarlo, e quindi non potremmo mai più scriverci, leggerci, né deallocarlo.
Va aggiunto che la quantità di memoria così allocata in modo arbitrario, è dinamica, ossia può essere variata utilizzando una specifica funzione di riallocazione della quantità di celle di memoria da utilizzare per la memorizzazione dei dati-Byte. La quantità - precedentemente stabilita in modo arbitrario - di celle/Byte di memoria, da riservare per la memorizzazione dei dati, può dunque essere modificata e reimpostata a volontà e più volte.
I linguaggi forniscono una speciale Variabile preposta a contenere il numero che rappresenta l'indirizzo di memoria del Byte o dei Byte di memoria arbitrariamente allocati dal programmatore [nota 5]. Si dice che questa speciale Variabile semplicemente "punta" (cioè indica, si riferisce) all'indirizzo di memoria della cella/Byte, se trattasi di dato monoByte, ovvero della cella/Byte, se trattasi di dati multiByte, più a sinistra che rappresenta il valore memorizzato.
Pertanto questa speciale Variabile, che ci dice da quale indirizzo di memoria cominciare a scrivere o a leggere, viene chiamata "Puntatore", ed essa stessa è nativa del linguaggio di programmazione utilizzato (facendo così parte della tipologia delle Variabili a quantità di celle allocabili predefinita) rappresenta l'allocazione automatica, predefinita e fissa di una quantità di memoria adeguata per contenere appunto il numero di un indirizzo di memoria.
Ovviamente per sapere quanti Byte deve poter scrivere o leggere, il sistema fa riferimento al numero impostato nella specifica funzione in sede di allocazione dell'area di memoria in questione, e alla quale il Puntatore punta (cioè della quale il Puntatore possiede il numero dell'indirizzo di memoria dell'unico Byte oppure del primo Byte più a sinistra).
Nel codice per poter accedere al valore dell'area di memoria puntata dalla variabile di tipo Puntatore, quest'ultima deve essere "dereferenziata".
Deallocazione di un'area allocata arbitrariamente
Poiché una quantità di memoria allocata arbitrariamente non viene deallocata automaticamente dal sistema, a tale compito deve provvedere il programmatore all'interno del codice con un'apposita funzione prevista dal linguaggio di programmazione utilizzato.
Come ormai è noto, la liberazione dell'area di memoria, precedentemente allocata, la restituisce alla sua originaria disponibilità di essere nuovamente riallocata da una diversa risorsa per diverse finalità.
Note
[1] La CPU può effettuare soltanto operazioni in aritmetica binaria: somma e differenza, scorrimento (shift) dei bit, operazioni logiche.
[2] Poiché in Gambas attualmente i tipi di dati superiori al "Byte" supportano sia numeri positivi che numeri negativi, una metà dell'ambitus di rappresentabilità dei valori è dedicata a quelli positivi e l'altra metà è usata per rappresentare i valori negativi. Pertanto il tipo di dato con risoluzione a 16-bit (Short) è capace di rappresentare numeri da -32.768 fino +32.767.
[3] La memoria deve essere riservata prima di essere impegnata.
[4] Il concetto di "variabile automatica" è particolarmente legato alla "visibilità" della variabile medesima: una variabile dichiarata all'interno di una routine cessa di esistere automaticamente, quando il processo esce da quella routine ove la variabile è stata dichiarata. Pertanto una variabile "automatica" per definizione è la variabile "locale".
[5] Va precisato, però, che in vari linguaggi di programmazione, come in Gambas, la variabile di tipo Puntatore può contenere anche l'indirizzo di memoria di una variabile nativa automatica, di cui alla tipologia prevista dal linguaggio di programmazione usato (non escluso l'indirizzo di memoria di un'altra variabile di tipo Puntatore). In questi casi - come è ben comprensibile - l'area di memoria è già allocata all'atto dell'uso della variabile nativa, predefinita e fissa, quindi allocata automaticamente. Il Puntatore semplicemente e solo conterrà il numero dell'indirizzo di tale variabile nativa.