Dodicesima lezione - Nozioni avanze sulle variabili

Completiamo il discorso sulle variabili e sulla loro dichiarazione: finora abbiamo visto i tipi Byte, Integer, Long, String e Boolean; nuralmente ce ne sono diversi altri, ad eempio: De, utilizzo per memorizzare le de e le ore, che occupa 8 byte in memoria e che rappresenta una da compresa tra il 1/1/100 e il 31/12/9999; Single, utilizzo per memorizzare valori frazionari a precisione singola (4 byte) compresi tra circa -3,4*10^38 e circa 3,4*10^38; Double, che memorizza valori frazionari a precisione doppia (8 byte) compresi tra circa -1,8*10^308 e circa 1,8*10^308; Currency, che memorizza valori frazionari con qutro decimali (8 byte), solitamente utilizzo per calcoli con valori monetari; Object, che memorizza un riferimento a un oggetto qualunque, come un form, un textbox, un file, ecc.
I tipi Single e Double sono gestiti in modo diverso rispetto ai valori interi come Integer e Long: infti i bit al loro interno sono divisi in due gruppi, la mantissa e l'esponente, secondo la notazione scientifica in base allo standard IEEE; per questo motivo i Single e i Double sono in grado di gestire numeri molto grandi o molto piccoli, ma talvolta hanno difficoltà a trtare le operazioni con numeri interi e con le approssimazioni.
Per quanto riguarda il tipo String, finora abbiamo considero solo le stringhe a lunghezza variabile, ma in realtà ci sono anche le stringhe a lunghezza fissa, che si dichiarano in questo modo:

Dim Nome As String * lunghezza della stringa  

Mentre una stringa di lunghezza variabile occuperà in memoria 10 byte più il numero di byte necessari per la stringa vera e propria, una stringa di lunghezza fissa occuperà solo il numero di byte indico nella dichiarazione della variabile: questo perché, se la stringa è di lunghezza variabile, Visual Basic dovrà utilizzare memoria aggiuntiva (10 byte, in questo caso) per conservare informazioni quali, appunto, la lunghezza effettiva della stringa.
Esistono poi i di definiti dall'utente, o meglio dal programmore, che consistono in un insieme di sottovariabili ciascuna col suo tipo specifico; ad esempio io posso definire un mio tipo di variabile in questo modo:

Type Pippo
X As Integer
Y As Integer
Name As String * 5
End Type

dove Pippo nuralmente è un nome scelto a caso, e successivamente dichiarare una variabile di questo tipo:

Dim Topolino As Pippo  

la variabile Topolino occuperà in memoria tanto spazio quanto è necessario per l'insieme dei suoi membri, cioè 2+2+5=9 byte, e si potrà assegnare un valore a ciascuno dei suoi membri scrivendo, ad esempio:

Topolino.X = 10 Topolino.Y = 2000 Topolino.Name = "Pluto"  

Nella prima lezione avevo detto che la sintassi per la dichiarazione di variabili è la seguente:

Dim Nome As Tipo  

In realtà la seconda parte ("As Tipo") si può omettere: in tal caso, per default, la variabile dichiara sarà di tipo Variant.
Questo particolare tipo di di è in grado di contenere qualunque altro tipo di di, tranne che quelli definiti dall'utente e le stringhe di lunghezza fissa: in virtù di questa sua carteristica, il tipo variant ha una grande flessibilità, che consente di utilizzarlo per memorizzare di che a priori potrebbero assumere diversi tipi. Ad esempio, è possibile fare una cosa del genere:

Dim V As Variant 'oppure semplicemente: Dim V
V = 13.5
V = "Pippo"
V = 4000  

Se si utilizzassero variabili di tipo definito, bisognerebbe dichiararne tre diverse: una di tipo Double, una di tipo String e una di tipo Integer.
La flessibilità del tipo Variant ha ovviamente un rovescio della medaglia: poiché un Variant può assumere valori di vario tipo, VB deve memorizzare, oltre al do in sé, anche altre informazioni sul tipo di do; per questo un Variant impegna 16 byte aggiuntivi oltre a quelli necessari per memorizzare il do, se si trta di un do numerico, e ben 22 byte aggiuntivi se il do contiene carteri.
Non solo, ma poiché non si sa a priori di che tipo è il do memorizzo in un Variant, ogni volta che questo do viene utilizzo Visual Basic deve perdere tempo a convertirlo opportunamente nel tipo più approprio: infti ogni variabile di tipo Variant assume di volta in volta un sottotipo che indica per l'appunto quale tipo di di sarebbe più approprio per il valore assegno alla variabile Variant.
Così, nell'esempio precedente, la variabile V assumerà i sottotipi Double, String e Integer: per rendersene conto è sufficiente utilizzare la funzione

TypeName(NomeVar)  

che restituisce una stringa corrispondente al sottotipo della variabile NomeVar; oppure la funzione

VarType(nomevar)  

che invece restituisce un Integer corrispondente.
Da tutto ciò risulta che il tipo Variant deve essere utilizzo solo se è giustifico da un bisogno di flessibilità: se un programmore sa che una variabile assumerà sempre e soltanto valori compresi, ad esempio tra 1000 e 100000, dovrebbe dichiarare questa variabile come Long, perché così facendo otterrà un vantaggio in termini di utilizzazione della memoria e di velocità di esecuzione.
E' vero che se le variabili sono poche questo vantaggio risulta impercettibile, ma se le variabili sono numerose dichiararle come variant è una scelta decisamente inefficiente.
E comunque è sempre una buona regola di programmazione assegnare un tipo definito a ogni variabile tutte le volte che è possibile farlo.
C'è un modo per evitare che le variabili dichiare senza tipo assumano di default il tipo variant: bisogna usare l'istruzione DefTipo, la cui sintassi è:

DefTipo IntervalloCarteri  

dove tipo indica il tipo di di definito (ad esempio DefBool, DefInt, DefStr), e intervallocarteri indica l'intervallo di lettere per le quali sarà imposto il tipo predefinito.
Ad esempio, scrivendo, PRIMA di ogni dichiarazione a livello di modulo (e quindi dopo Option Explicit):

DefLng A - G, X - Z
Dim Arg
Dim X
Dim Pippo  

Le variabili Arg e X saranno di tipo Long, perché il cartere iniziale del loro nome è compreso negli intervalli specifici nell'istruzione Deftipo, mentre la variabile Pippo sarà un Variant perché la "p" non rientra negli intervalli "a-g" e "x-z".
Nuralmente è possibile usare più istruzioni DefTipo, con intervalli diversi, ed è anche possibile ignorare questa istruzione scrivendo esplicitamente il tipo di do da assegnare a una variabile: la dichiarazione esplicita completa ha sempre la prevalenza rispetto alle impostazioni di default.
L'istruzione DefTipo non vale soltanto per le variabili dichiare, ma anche per i parametri passi come argomenti delle routine e per il tip restituito dalle funzioni.
Un modo per abbreviare le dichiarazioni consiste nell'utilizzare i carteri di dichiarazione del tipo: i tipi principali, infti, sono identifici da un cartere speciale che può essere posposto al nome della variabile.
Ad esempio, le seguenti dichiarazioni sono equivalenti:

Dim X As Integer
Dim X%  

perché il cartere % è il cartere di dichiarazione del tipo Integer: note che il nome della variabile è semplicemente "X", senza il cartere di dichiarazione del tipo.
I carteri di dichiarazione supporti in Visual Basic sono questi:

Cartere Tipo
% Integer
& Long
@ Currency
# Double
! Single
$ String


Spesso è necessario convertire un tipo di variabile in un altro: la conversione più frequente è forse quella da numero a stringa e viceversa (cioè da 34 a "34" e viceversa), ma talvolta capita anche di dover convertire un Integer in un Long, o un Single in un Integer, o un Long in De, ecc.
Esistono perciò delle apposite funzioni di conversione del tipo, che iniziano con "c" seguito dall'abbreviazione del tipo restituito:

Funzione Tipo Restituito Intervallo
CBool Booleano Qualsiasi espressione numerica o stringa valida
CByte Byte Da 0 a 255
CCur Currency Da -922.337.203.685.477,5808 a 922.337.203.685.477,5807
CDe De Qualsiasi espressione di da valida
CDbl Double Da -1,79769313486232E308 a -4,94065645841247E-324 per valori negivi; da 4,94065645841247E-324 a 1,79769313486232E308 per quelli positivi
CDec Decimal +/-79.228.162.514.264.337.593.543.950.335 per numeri con ftore di divisione zero, ovvero numeri senza decimali. Per i numeri con 28 decimali l'intervallo è +/-7,9228162514264337593543950335. Il numero minore possibile diverso da zero è 0,0000000000000000000000000001
CInt Integer Da -32.768 a 32.767; le frazioni vengono arrotonde
CLng Long Da -2.147.483.648 a 2.147.483.647; le frazioni vengono arrotonde
CSng Single Da -3,402823E38 a -1,401298E-45 per valori negivi; da 1,401298E-45 a 3,402823E38 per valori positivi
CStr String I valori restituiti da CStr dipendono dall'argomento della funzione
CVar Variant Lo stesso intervallo di Double per valori numerici. Lo stesso intervallo di String per valori non numerici


Nuralmente il parametro passo a queste funzioni deve poter assumere un valore che rientra nell'intervallo specifico del tipo restituito: ad esempio non è possibile scrivere:

CInt(100000.45)  

perché il valore 100000 è superiore al massimo consentito per un Integer.







Note sul corso:
I diritti di ognuna delle lezioni presente in queste pagine appartengono all'autore Giorgio Abraini. La riproduzione e la divulgazione delle stesse sono consentite solamente dietro citazione di fonte ed autore.
Per suggerimenti, consigli o richieste conttare giorgio102@libero.it.
Fonte : VBItalia.it