2. Nozioni di base sul linguaggio VB.NET
2.1. Introduzione
Tratteremo inizialmente il VB.NET come un linguaggio di programmazione classico. Affronteremo gli oggetti in un secondo momento.
In un programma si trovano due elementi
- i dati
- le istruzioni che li manipolano
In genere si cerca di separare i dati dalle istruzioni:
![]() |
2.2. I dati di VB.NET
VB.NET utilizza i seguenti tipi di dati:
- numeri interi, reali e decimali
- caratteri e stringhe di caratteri
- i valori booleani
- le date
- gli oggetti
2.2.1. I tipi di dati predefiniti
Tipo VB | Tipo .NET equivalente | Dimensione | Intervallo di valori |
Booleano | System.Boolean | 2 byte | Vero o Falso. |
Byte | System.Byte | 1 byte | Da 0 a 255 (senza segno). |
Carattere | System.Char | 2 byte | Da 0 a 65.535 (senza segno). |
Data | System.DateTime | 8 byte | Da 0:00:00 del 1° gennaio 0001 a 23:59:59 del 31 dicembre 9999. |
Decimale | System.Decimal | 16 byte | da 0 a +/-79 228 162 514 264 337 593 543 950 335 senza decimali; da 0 a +/-7,9228162514264337593543950335 con 28 decimali; il numero più piccolo diverso da zero è +/-0,0000000000000000000000000001 (+/-1E-28). |
Doppio | System.Double | 8 byte | da -1,79769313486231E+308 a -4,94065645841247E-324 per i valori negativi; da 4,94065645841247E-324 a 1,79769313486231E+308 per i valori positivi. |
Intero | System.Int32 | 4 byte | da -2 147 483 648 a 2 147 483 647. |
Long | System.Int64 | 8 byte | da -9 223 372 036 854 775 808 a 9 223 372 036 854 775 807. |
Oggetto | System.Object | 4 byte | In una variabile di tipo Object è possibile memorizzare qualsiasi tipo. |
Short | System.Int16 | 2 byte | Da -32 768 a 32 767. |
Single | System.Single | 4 byte | da -3,402823E+38 a -1,401298E-45 per i valori negativi; da 1,401298E-45 a 3,402823E+38 per i valori positivi. |
Stringa | System.String (classe) | Da 0 a circa 2 miliardi di caratteri Unicode. |
Nella tabella sopra riportata si nota che esistono due possibili tipi per un intero a 32 bit: Integer e System.Int32. I due tipi sono intercambiabili. Lo stesso vale per gli altri tipi VB e i loro equivalenti nella piattaforma .NET. Ecco un esempio di programma:
Module types
Sub Main()
' numeri interi
Dim var1 As Integer = 100
Dim var2 As Long = 10000000000L
Dim var3 As Byte = 100
Dim var4 As Short = 4
' numeri reali
Dim var5 As Decimal = 4.56789D
Dim var6 As Double = 3.4
Dim var7 As Single = -0.000103F
' data
Dim var8 As Date = New Date(2003, 1, 1, 12, 8, 4)
' booleano
Dim var9 As Boolean = True
' carattere
Dim var10 As Char = "A"c
' stringa di caratteri
Dim var11 As String = "abcde"
' oggetto
Dim var12 As Object = New Object
' visualizzazioni
Console.Out.WriteLine("var1=" + var1.ToString)
Console.Out.WriteLine("var2=" + var2.ToString)
Console.Out.WriteLine("var3=" + var3.ToString)
Console.Out.WriteLine("var4=" + var4.ToString)
Console.Out.WriteLine("var5=" + var5.ToString)
Console.Out.WriteLine("var6=" + var6.ToString)
Console.Out.WriteLine("var7=" + var7.ToString)
Console.Out.WriteLine("var8=" + var8.ToString)
Console.Out.WriteLine("var9=" + var9.ToString)
Console.Out.WriteLine("var10=" + var10)
Console.Out.WriteLine("var11=" + var11)
Console.Out.WriteLine("var12=" + var12.ToString)
End Sub
End Module
L'esecuzione produce i seguenti risultati:
var1=100
var2=10000000000
var3=100
var4=4
var5=4,56789
var6=3,4
var7=-0,000103
var8=01/01/2003 12:08:04
var9=True
var10=A
var11=abcde
var12=System.Object
2.2.2. Notazione dei dati letterali
145, -7, &FF (esadecimale) | |
100000L | |
134,789, -45E-18 (-45 × 10⁻¹⁸) | |
134.789F, -45E-18F (-45 10⁻¹⁸) | |
100000D | |
"A"c | |
"oggi" | |
vero, falso | |
New Date(2003, 1, 1) per il 01/01/2003 |
Si notino i seguenti punti:
- 100000L, la L indica che il numero è considerato un intero lungo
- 134.789F, la F indica che il numero è considerato un numero reale a precisione singola
- 100000D, la D indica che il numero è considerato un numero reale decimale
- "A"c, per trasformare la stringa di caratteri "A" nel carattere 'A'
- La stringa è racchiusa tra i caratteri ". Se la stringa deve contenere il carattere ", quest'ultimo va ripetuto due volte, come in "abcd""e", per rappresentare la stringa [abcd"e].
2.2.3. Dichiarazione dei dati
2.2.3.1. Ruolo delle dichiarazioni
Un programma gestisce dati caratterizzati da un nome e da un tipo. Questi dati vengono memorizzati in memoria. Al momento della compilazione del programma, il compilatore assegna a ciascun dato una posizione in memoria caratterizzata da un indirizzo e da una dimensione. Lo fa avvalendosi delle dichiarazioni effettuate dal programmatore. Inoltre, queste dichiarazioni consentono al compilatore di individuare eventuali errori di programmazione. Ad esempio, l’operazione x=x*2 verrà segnalata come errata se x è una stringa di caratteri.
2.2.3.2. Dichiarazione delle costanti
La sintassi per la dichiarazione di una costante è la seguente:
const identificatore as tipo=valore
ad esempio [const PI as double=3.141592]. Perché dichiarare le costanti?
- La lettura del programma risulterà più agevole se alla costante viene assegnato un nome significativo: [const taux_tva as single=0.186F]
- La modifica del programma risulterà più semplice se la "costante" dovesse cambiare. Pertanto, nel caso precedente, se l'aliquota IVA passasse al 33%, l'unica modifica da apportare sarebbe quella di modificare l'istruzione che ne definisce il valore: [const taux_tva as single=0.336F]. Se invece si fosse utilizzato esplicitamente 0,186 nel programma, sarebbe stato necessario modificare numerose istruzioni.
2.2.3.3. Dichiarazione delle variabili
Una variabile è identificata da un nome e si riferisce a un tipo di dati. VB.NET non fa distinzione tra maiuscole e minuscole. Pertanto, le variabili FIN e fin sono identiche. Le variabili possono essere inizializzate al momento della loro dichiarazione. La sintassi per dichiarare una o più variabili è:
dim variabile1, variabile2, ..., variabile n as identificatore_di_tipo
dove identificateur_de_type è un tipo predefinito oppure un tipo definito dal programmatore.
2.2.4. Le conversioni tra numeri e stringhe di caratteri
nombre.ToString oppure "" & numero oppure CType(numero,String) | |
objet.ToString | |
Integer.Parse(stringa) oppure Int32.Parse | |
Long.Parse (stringa) o Int64.Parse | |
Double.Parse (stringa) | |
Single.Parse(stringa) |
La conversione di una stringa in un numero potrebbe non andare a buon fine se la stringa non rappresenta un numero valido. In tal caso viene generato un errore fatale denominato eccezione in VB.NET. Questo errore può essere gestito tramite la seguente clausola try/catch:
try
appel de la fonction susceptible de générer l'exception
catch e as Exception
traiter l'exception e
end try
instruction suivante
Se la funzione non genera un'eccezione, si passa all'istruzione successiva; in caso contrario, si passa al corpo della clausola catch e poi all'istruzione successiva. Torneremo in seguito sulla gestione delle eccezioni. Ecco un programma che illustra le principali tecniche di conversione tra numeri e stringhe di caratteri. In questo esempio la funzione visualizza sullo schermo il valore del proprio parametro. Pertanto, affiche(S) visualizza il valore di S sullo schermo.
' direttive
Option Strict On
' spazi dei nomi importati
Imports System
' il modulo di test
Module Module1
Sub Main()
' procedura principale
' dati locali
Dim S As String
Const i As Integer = 10
Const l As Long = 100000
Const f As Single = 45.78F
Dim d As Double = -14.98
' numero --> stringa
affiche(CType(i, String))
affiche(CType(l, String))
affiche(CType(f, String))
affiche(CType(d, String))
'booleano --> stringa
Const b As Boolean = False
affiche(b.ToString)
' stringa --> int
Dim i1 As Integer = Integer.Parse("10")
affiche(i1.ToString)
Try
i1 = Integer.Parse("10.67")
affiche(i1.ToString)
Catch e As Exception
affiche("Erreur [10.67] : " + e.Message)
End Try
' stringa --> long
Dim l1 As Long = Long.Parse("100")
affiche("" + l1.ToString)
Try
l1 = Long.Parse("10.675")
affiche("" & l1)
Catch e As Exception
affiche("Erreur [10.675] : " + e.Message)
End Try
' stringa --> double
Dim d1 As Double = Double.Parse("100,87")
affiche(d1.ToString)
Try
d1 = Double.Parse("abcd")
affiche("" & d1)
Catch e As Exception
affiche("Erreur [abcd] : " + e.Message)
End Try
' stringa --> single
Dim f1 As Single = Single.Parse("100,87")
affiche(f1.ToString)
Try
d1 = Single.Parse("abcd")
affiche(f1.ToString)
Catch e As Exception
affiche("Erreur [abcd] : " + e.Message)
End Try
End Sub
' visualizza
Public Sub affiche(ByVal S As String)
Console.Out.WriteLine("S=" + S)
End Sub
End Module
I risultati ottenuti sono i seguenti:
S=10
S=100000
S=45,78
S=-14,98
S=False
S=10
S=Erreur [10.67] : Le format de la chaîne d'entrée est incorrect.
S=100
S=Erreur [10.675] : Le format de la chaîne d'entrée est incorrect.
S=100,87
S=Erreur [abcd] : Le format de la chaîne d'entrée est incorrect.
S=100,87
S=Erreur [abcd] : Le format de la chaîne d'entrée est incorrect.
Si noti che i numeri reali sotto forma di stringa di caratteri devono utilizzare la virgola e non il punto decimale. Pertanto si scriverà Dim d As Double = -14.98 ma Dim d1 As Double = Double.Parse("100,87")
2.2.5. Gli array di dati
Un array VB.NET è un oggetto che consente di raggruppare sotto un unico identificatore dati dello stesso tipo. La sua dichiarazione è la seguente:
Dim Tabella(n) as tipo oppure Dim Tabella() as tipo = New tipo(n) {}
dove n è l'indice dell'ultimo elemento dell'array. La sintassi Tableau(i) indica il dato n. i, dove i appartiene all'intervallo [0,n]. Qualsiasi riferimento al dato Tableau(i), dove i non appartiene all'intervallo [0,n], provocherà un'eccezione. Un array può essere inizializzato contemporaneamente alla sua dichiarazione. In questo caso, non è necessario specificare il numero dell'ultimo elemento.
Dim entiers() As Integer = {0, 10, 20, 30}
Gli array hanno una proprietà Length che corrisponde al numero di elementi dell’array. Ecco un programma di esempio:
Module tab0
Sub Main()
' una prima tabella
Dim tab0(5) As Integer
For i As Integer = 0 To UBound(tab0)
tab0(i) = i
Next
For i As Integer = 0 To UBound(tab0)
Console.Out.WriteLine("tab0(" + i.ToString + ")=" + tab0(i).tostring)
Next
' un secondo quadro
Dim tab1() As Integer = New Integer(5) {}
For i As Integer = 0 To tab1.Length - 1
tab1(i) = i * 10
Next
For i As Integer = 0 To tab1.Length - 1
Console.Out.WriteLine("tab1(" + i.ToString + ")=" + tab1(i).tostring)
Next
End Sub
End Module
e la sua esecuzione:
tab0(0)=0
tab0(1)=1
tab0(2)=2
tab0(3)=3
tab0(4)=4
tab0(5)=5
tab1(0)=0
tab1(1)=10
tab1(2)=20
tab1(3)=30
tab1(4)=40
tab1(5)=50
Un array bidimensionale può essere dichiarato come segue:
Dim Tabella(n,m) as Tipo oppure Dim Tabella(,) as Tipo = New Tipo(n,m) {}
dove n+1 è il numero di righe, m+1 il numero di colonne. La sintassi Tableau(i,j) indica l'elemento j della riga i di Tableau. Anche l'array bidimensionale può essere inizializzato contemporaneamente alla sua dichiarazione:
Dim réels(,) As Double = {{0.5, 1.7}, {8.4, -6}}
Il numero di elementi in ciascuna delle dimensioni può essere ottenuto tramite il metodo GetLenth(i), dove i=0 rappresenta la dimensione corrispondente al primo indice, i=1 quella corrispondente al secondo indice, … Ecco un programma di esempio:
Module Module2
Sub Main()
' una prima tabella
Dim tab0(2, 1) As Integer
For i As Integer = 0 To UBound(tab0)
For j As Integer = 0 To tab0.GetLength(1) - 1
tab0(i, j) = i * 10 + j
Next
Next
For i As Integer = 0 To UBound(tab0)
For j As Integer = 0 To tab0.GetLength(1) - 1
Console.Out.WriteLine("tab0(" + i.ToString + "," + j.ToString + ")=" + tab0(i, j).tostring)
Next
Next
' un secondo quadro
Dim tab1(,) As Integer = New Integer(2, 1) {}
For i As Integer = 0 To tab1.GetLength(0) - 1
For j As Integer = 0 To tab1.GetLength(1) - 1
tab1(i, j) = i * 100 + j
Next
Next
For i As Integer = 0 To tab1.GetLength(0) - 1
For j As Integer = 0 To tab1.GetLength(1) - 1
Console.Out.WriteLine("tab1(" + i.ToString + "," + j.ToString + ")=" + tab1(i, j).tostring)
Next
Next
End Sub
End Module
e i risultati della sua esecuzione:
tab0(0)=0
tab0(1)=1
tab0(2)=2
tab0(3)=3
tab0(4)=4
tab0(5)=5
tab1(0)=0
tab1(1)=10
tab1(2)=20
tab1(3)=30
tab1(4)=40
tab1(5)=50
Un array di array viene dichiarato come segue:
Dim Tabella(n)() as Tipo oppure Dim Tabella()() as Tipo = new Tipo(n)()
La dichiarazione sopra riportata crea un array di n+1 righe. Ogni elemento Array(i) è un riferimento a un array unidimensionale. Questi array non vengono creati al momento della dichiarazione sopra riportata. L'esempio seguente illustra la creazione di un array di array:
' una tabella di tabelle
Dim noms()() As String = New String(3)() {}
' inizializzazione
For i = 0 To noms.Length - 1
noms(i) = New String(i) {}
For j = 0 To noms(i).Length - 1
noms(i)(j) = "nom" & i & j
Next
Next
Qui noms(i) è un array di i+1 elementi. Poiché noms(i) è un array, noms(i).Length rappresenta il numero dei suoi elementi. Ecco un esempio che riunisce i tre tipi di array appena presentati:
' direttive
Option Strict On
Option Explicit On
' importazioni
Imports System
' classe di test
Module test
Sub main()
' un array unidimensionale inizializzato
Dim entiers() As Integer = {0, 10, 20, 30}
Dim i As Integer
For i = 0 To entiers.Length - 1
Console.Out.WriteLine("entiers[" & i & "]=" & entiers(i))
Next
' un array bidimensionale inizializzato
Dim réels(,) As Double = {{0.5, 1.7}, {8.4, -6}}
Dim j As Integer
For i = 0 To réels.GetLength(0) - 1
For j = 0 To réels.GetLength(1) - 1
Console.Out.WriteLine("réels[" & i & "," & j & "]=" & réels(i, j))
Next
Next
' un array di array
Dim noms()() As String = New String(3)() {}
' inizializzazione
For i = 0 To noms.Length°- 1
noms(i) =°New String(i) {}
For j = 0 To noms(i).Length - 1
noms(i)(j) = "nom" & i & j
Next
Next
' visualizzazione
For i = 0 To noms.Length°- 1
For j = 0 To noms(i).Length - 1
Console.Out.WriteLine("noms[" & i & "][" & j & "]=" & noms(i)(j))
Next
Next
End Sub
End Module
All’esecuzione, otteniamo i seguenti risultati:
entiers[0]=0
entiers[1]=10
entiers[2]=20
entiers[3]=30
réels[0,0]=0,5
réels[0,1]=1,7
réels[1,0]=8,4
réels[1,1]=-6
noms[0][0]=nom00
noms[1][0]=nom10
noms[1][1]=nom11
noms[2][0]=nom20
noms[2][1]=nom21
noms[2][2]=nom22
noms[3][0]=nom30
noms[3][1]=nom31
noms[3][2]=nom32
noms[3][3]=nom33
2.3. Istruzioni di base per VB.NET
Si distingue
1 le istruzioni elementari eseguite dal computer.
2 le istruzioni di controllo dello svolgimento del programma.
Le istruzioni elementari risultano evidenti se si considera la struttura di un microcomputer e delle sue periferiche.
![]() |
-
lettura delle informazioni provenienti dalla tastiera
-
elaborazione delle informazioni
-
scrittura di informazioni sullo schermo
-
lettura delle informazioni da un file su disco
-
scrittura di informazioni in un file su disco
2.3.1. Scrittura sullo schermo
Esistono diverse istruzioni per la scrittura sullo schermo:
Console.Out.WriteLine(expression)
Console.WriteLine(expression)
Console.Error.WriteLine (expression)
dove expression rappresenta qualsiasi tipo di dato che possa essere convertito in una stringa di caratteri per essere visualizzato sullo schermo. Negli esempi visti finora, abbiamo utilizzato solo l'istruzione Console.Out.WriteLine(espressione).
La classe System.Console consente di accedere alle operazioni di scrittura su schermo (Write, WriteLine). La classe Console presenta due proprietà, Out ed Error, che sono flussi di scrittura di tipo StreamWriter:
- Console.WriteLine() è equivalente a Console.Out.WriteLine() e scrive sul flusso Out solitamente associato allo schermo.
- Console.Error.WriteLine() scrive sul flusso Error, solitamente anch’esso associato allo schermo.
I flussi Out e Error sono associati per impostazione predefinita allo schermo. Tuttavia, possono essere reindirizzati verso file di testo al momento dell’esecuzione del programma, come vedremo tra poco.
2.3.2. Lettura dei dati digitati dalla tastiera
Il flusso di dati proveniente dalla tastiera è rappresentato dall’oggetto Console.In di tipo StreamReader. Questo tipo di oggetti consente di leggere una riga di testo con il metodo ReadLine:
Dim ligne As String = Console.In.ReadLine()
La riga digitata sulla tastiera viene memorizzata nella variabile ligne e può quindi essere utilizzata dal flusso programme.Le. Il flusso In può essere reindirizzato verso un file, così come i flussi Out ed Error.
2.3.3. Esempio di operazioni di I/O
Ecco un breve programma che illustra le operazioni di input-output da tastiera/schermo:
' opzioni
Option Explicit On
Option Strict On
' spazi dei nomi
Imports System
' modulo
Module io1
Sub Main()
' scrittura sul flusso Out
Dim obj As New Object
Console.Out.WriteLine(("" & obj.ToString))
' scrittura sul flusso Error
Dim i As Integer = 10
Console.Error.WriteLine(("i=" & i))
' lettura di una riga immessa da tastiera
Console.Out.Write("Tapez une ligne : ")
Dim ligne As String = Console.In.ReadLine()
Console.Out.WriteLine(("ligne=" + ligne))
End Sub
End Module
e i risultati dell'esecuzione:
Le istruzioni
Dim obj As New Object
Console.Out.WriteLine(obj.ToString)
servono solo a dimostrare che qualsiasi oggetto può essere visualizzato. In questa sede non cercheremo di spiegare il significato di ciò che viene visualizzato.
2.3.4. Reindirizzamento delle I/O
In DOS/Windows esistono tre periferiche standard denominate:
- periferica di ingresso standard - indica per impostazione predefinita la tastiera e porta il n. 0
- periferica di uscita standard - indica per impostazione predefinita lo schermo e ha il numero 1
- periferica di errore standard - indica per impostazione predefinita lo schermo e ha il n. 2
In VB.NET, il flusso di scrittura Console.Out scrive sul dispositivo 1, il flusso di scrittura Console.Error scrive sul dispositivo 2 e il flusso di lettura Console.In legge i dati provenienti dal dispositivo 0. Quando si avvia un programma in una finestra DOS in Windows, è possibile specificare quali saranno i dispositivi 0, 1 e 2 per il programma in esecuzione. Consideriamo la seguente riga di comando:
Utilizzando gli argomenti argi del programma pg, è possibile reindirizzare le periferiche di I/O standard verso dei file:
il flusso di ingresso standard n. 0 viene reindirizzato al file in.txt. Nel programma, il flusso Console.In preleverà quindi i propri dati dal file in.txt. | |||
reindirizza l'uscita n. 1 verso il file out.txt. Di conseguenza, nel programma il flusso Console.Out scriverà i propri dati nel file out.txt | |||
idem, ma i dati scritti vengono aggiunti al contenuto attuale del file out.txt. | |||
reindirizza l'uscita n. 2 verso il file error.txt. Ciò comporta che nel programma il flusso Console.Error scriverà i propri dati nel file error.txt | |||
idem, ma i dati scritti vengono aggiunti al contenuto attuale del file error.txt. | |||
Le periferiche 1 e 2 vengono entrambe reindirizzate verso dei file | |||
Si noti che per reindirizzare i flussi di I/O del programma pg verso dei file, non è necessario modificare il programma pg. È il programma OS che definisce la natura delle periferiche 0, 1 e 2. Consideriamo il seguente programma:
' opzioni
Option Explicit On
Option Strict On
' spazi dei nomi
Imports System
' reindirizzamenti
Module console2
Sub Main()
' lettura del flusso In
Dim data As String = Console.In.ReadLine()
' scrittura flusso Out
Console.Out.WriteLine(("écriture dans flux Out : " + data))
' scrittura flusso Error
Console.Error.WriteLine(("écriture dans flux Error : " + data))
End Sub
End Module
Compiliamo questo programma:
dos>vbc es2.vb
Compilateur Microsoft (R) Visual Basic .NET version 7.10.3052.4 pour Microsoft (R) .NET Framework version 1.1.4322.573
Copyright (C) Microsoft Corporation 1987-2002. Tous droits réservés.
dos>dir
24/02/2004 15:39 416 es2.vb
11/03/2004 08:20 3 584 es2.exe
Eseguiamo una prima esecuzione:
dos>es2.exe
un premier test
écriture dans flux Out : un premier test
écriture dans flux Error : un premier test
L'esecuzione precedente non reindirizza nessuno dei flussi di I/O standard In, Out, Error. Ora reindirizzeremo tutti e tre i flussi. Il flusso In verrà reindirizzato verso il file in.txt, il flusso Out verso il file out.txt, il flusso Error verso il file error.txt. Questo reindirizzamento avviene nella riga di comando nella forma
L'esecuzione produce i seguenti risultati:
dos>more in.txt
un second test
dos>es2.exe 0<in.txt 1>out.txt 2>error.txt
dos>more out.txt
écriture dans flux Out : un second test
dos>more error.txt
écriture dans flux Error : un second test
Si vede chiaramente che i flussi Out e Error non scrivono sugli stessi dispositivi.
2.3.5. Assegnazione del valore di un'espressione a una variabile
Ci si concentra qui sull'operazione variable=expression. L'espressione può essere di tipo: aritmetico, relazionale, booleano, stringa.
2.3.5.1. Elenco degli operatori
Azione | Elemento del linguaggio |
^, –, *, /, \, Mod, +, = | |
=, ^=, *=, /=, \=, +=, -=, &= | |
=, <>, <, >, <=, >=, Like, Is | |
&, + | |
Not, And, Or, Xor, AndAlso, OrElse | |
AddressOf, GetType |
2.3.5.2. Espressione aritmetica
Gli operatori delle espressioni aritmetiche sono i seguenti:
^, –, *, /, \, Mod, +, = |
+: addizione, -: sottrazione, *: moltiplicazione, /: divisione decimale, \: quoziente della divisione intera, Mod: resto della divisione intera, ^: elevamento a potenza. Pertanto, il seguente programma:
' operatori aritmetici
Module operateursarithmetiques
Sub Main()
Dim i, j As Integer
i = 4 : j = 3
Console.Out.WriteLine(i & "/" & j & "=" & (i / j))
Console.Out.WriteLine(i & "\" & j & "=" & (i \ j))
Console.Out.WriteLine(i & " mod " & j & "=" & (i Mod j))
Dim r1, r2 As Double
r1 = 4.1 : r2 = 3.6
Console.Out.WriteLine(r1 & "/" & r2 & "=" & (r1 / r2))
Console.Out.WriteLine(r1 & "^2=" & (r1 ^ 2))
Console.Out.WriteLine(Math.Cos(3))
End Sub
End Module
fornisce i seguenti risultati:
Esistono diverse funzioni matematiche. Eccone alcune:
| radice quadrata |
| Coseno |
| Sen |
| Tangente |
| x alla potenza y (x>0) |
| Esponenziale |
| Logaritmo naturale |
| valore assoluto |
Tutte queste funzioni sono definite in una classe denominata Math. Quando le si utilizza, è necessario anteporre il nome della classe in cui sono definite. Pertanto, si scriverà:
La definizione completa della classe Math è la seguente:
Rappresenta la base del logaritmo naturale specificata dalla costante e. | |||
Rappresenta il rapporto tra la circonferenza di un cerchio e il suo diametro, specificato dalla costante π. | |||
Sovraccaricato. Restituisce il valore assoluto di un numero specificato. | |||
Restituisce l'angolo il cui coseno è il numero specificato. | |||
Restituisce l'angolo il cui seno è il numero specificato. | |||
Restituisce l'angolo la cui tangente è il numero specificato. | |||
Restituisce l'angolo la cui tangente è il quoziente di due numeri specificati. | |||
Genera il prodotto intero di due numeri a 32 bit. | |||
Restituisce il numero intero più piccolo maggiore o uguale al numero specificato. | |||
Restituisce il coseno dell'angolo specificato. | |||
Restituisce il coseno iperbolico dell'angolo specificato. | |||
Sovraccaricato. Restituisce il quoziente di due numeri, passando il resto come parametro di output. | |||
Restituisce e elevato alla potenza specificata. | |||
Restituisce il numero intero più grande minore o uguale al numero specificato. | |||
Restituisce il resto della divisione di un numero specificato per un altro. | |||
Sovraccaricato. Restituisce il logaritmo di un numero specificato. | |||
Restituisce il logaritmo in base 10 di un numero specificato. | |||
Sovraccaricato. Restituisce il più grande tra due numeri specificati. | |||
Sovraccaricato. Restituisce il più piccolo tra due numeri. | |||
Restituisce un numero specificato elevato alla potenza specificata. | |||
Sovraccaricato. Restituisce il numero più vicino al valore specificato. | |||
Sovraccaricato. Restituisce un valore che indica il segno di un numero. | |||
Restituisce il seno dell'angolo specificato. | |||
Restituisce il seno iperbolico dell'angolo specificato. | |||
Restituisce la radice quadrata di un numero specificato. | |||
Restituisce la tangente dell'angolo specificato. | |||
Restituisce la tangente iperbolica dell'angolo specificato. | |||
Quando una funzione è dichiarata "sovraccaricata", significa che esiste per diversi tipi di parametri. Ad esempio, la funzione Abs(x) esiste per x di tipo Integer, Long, Decimal, Single, Float. Per ciascuno di questi tipi esiste una definizione separata della funzione Abs. Si dice quindi che è sovraccaricata.
2.3.5.3. Priorità nella valutazione delle espressioni aritmetiche
La priorità degli operatori nella valutazione di un'espressione aritmetica è la seguente (dal più prioritario al meno prioritario):
Categoria | Operatori |
Tutte le espressioni senza operatori: funzioni, parentesi | |
^ | |
+, - | |
*, / | |
\ | |
Mod | |
+, - |
2.3.5.4. Espressioni relazionali
Gli operatori sono i seguenti:
=, <>, <, >, <=, >=, Like, Is |
=: uguale a, <>: diverso da, <: minore di (stretto), >: maggiore di (stretto), <=: minore o uguale a, >=: maggiore o uguale a, Like: corrisponde a un modello, Is: identità degli oggetti. Tutti questi operatori hanno la stessa priorità. Vengono valutati da sinistra a destra. Il risultato di un'espressione relazionale è un valore booleano.
Confronto di stringhe di caratteri: consideriamo il seguente programma:
' spazi dei nomi
Imports System
Module string1
Sub main()
Dim ch1 As Char = "A"c
Dim ch2 As Char = "B"c
Dim ch3 As Char = "a"c
Console.Out.WriteLine("A<B=" & (ch1 < ch2))
Console.Out.WriteLine("A<a=" & (ch1 < ch3))
Dim chat As String = "chat"
Dim chien As String = "chien"
Dim chaton As String = "chaton"
Dim chat2 As String = "CHAT"
Console.Out.WriteLine("chat<chien=" & (chat < chien))
Console.Out.WriteLine("chat<chaton=" & (chat < chaton))
Console.Out.WriteLine("chat<CHAT=" & (chat < chat2))
Console.Out.WriteLine("chaton like chat*=" & ("chaton" Like "chat*"))
End Sub
End Module
e il risultato della sua esecuzione:
Siano dati due caratteri C1 e C2. È possibile confrontarli utilizzando gli operatori: <, <=, =, <>, >, >=. In questo caso vengono confrontati i valori Unicode dei caratteri, che sono numeri. Secondo l’ordinamento Unicode, si hanno le seguenti relazioni:
spazio < .. < '0' < '1' < .. < '9' < .. < 'A' < 'B' < .. < 'Z' < .. < 'a' < 'b' < .. < 'z'
Le stringhe vengono confrontate carattere per carattere. La prima disuguaglianza riscontrata tra due caratteri determina una disuguaglianza dello stesso segno sulle stringhe. Con queste spiegazioni, il lettore è invitato a studiare i risultati del programma precedente.
2.3.5.5. Espressioni booleane
Gli operatori sono i seguenti:
Not, And, Or, Xor, AndAlso, OrElse |
Not: e logico, Or: o logico, Not: negazione, Xor: o esclusivo.
op1 AndAlso op2: se op1 è falso, op2 non viene valutato e il risultato è falso.
op1 OrElse op2: se op1 è vero, op2 non viene valutato e il risultato è vero.
La priorità di questi operatori tra loro è la seguente:
Not | |
And, AndAlso | |
Oppure, OrElse | |
Xor |
Il risultato di un'espressione booleana è un valore booleano.
2.3.5.6. Operazioni sui bit
Da un lato si ritrovano gli stessi operatori degli operatori booleani con la stessa priorità. Si trovano inoltre due operatori di spostamento: << e >>. Siano i e j due numeri interi.
sposta i di n bit a sinistra. I bit che entrano sono zeri. | |
sposta i di n bit a destra. Se i è un numero intero con segno (signed char, int, long), il bit di segno viene mantenuto. | |
esegue l'OR logico bit per bit tra i e j. | |
esegue la logica bit per bit tra i e j (OU). | |
imposta i a 1 | |
crea i file OU e EXCLUSIF da i e j |
Si consideri il seguente programma:
Module operationsbit
Sub main()
' manipolazione dei bit
Dim i As Short = &H123F
Dim k As Short = &H7123
Console.Out.WriteLine("i<<4=" & (i << 4).ToString("X"))
Console.Out.WriteLine("i>>4=" & (i >> 4).ToString("X"))
Console.Out.WriteLine("k>>4=" & (k >> 4).ToString("X"))
Console.Out.WriteLine("i and 4=" & (i And 4).ToString("X"))
Console.Out.WriteLine("i or 4 =" & (i Or 4).ToString("X"))
Console.Out.WriteLine("not i=" & (Not i).ToString("X"))
End Sub
End Module
La sua esecuzione fornisce i seguenti risultati:
2.3.5.7. Operatore associato all'assegnazione
È possibile scrivere a+=b, che significa a=a+b. L'elenco degli operatori che possono essere combinati con l'operazione di assegnazione è il seguente:
^=, *=, /=, \=, +=, -=, &= |
2.3.5.8. Priorità generale degli operatori
Categoria | Operatori |
Tutte le espressioni senza operatore | |
^ | |
+, - | |
*, / | |
\ | |
Mod | |
+, - | |
& | |
<<, >> | |
=, <>, <, >, <=, >=, Like, Is, TypeOf...Is | |
Not | |
E, AndAlso | |
Oppure, OrElse | |
Xor |
Quando un operando è posto tra due operatori della stessa priorità, l'associatività degli operatori determina l'ordine in cui vengono eseguite le operazioni. Tutti gli operatori sono associativi a sinistra, il che significa che le operazioni vengono eseguite da sinistra a destra. La priorità e l'associatività possono essere controllate utilizzando espressioni tra parentesi.
2.3.5.9. Le conversioni di tipo
Esiste una serie di funzioni predefinite che consentono di passare da un tipo di dati a un altro. Il loro elenco è il seguente:
Queste funzioni accettano come argomento un'espressione numerica o una stringa di caratteri. Il tipo del risultato è indicato nella tabella seguente:
funzione | risultato | Intervallo di valori del parametro della funzione |
Booleano | Qualsiasi stringa o espressione numerica valida. | |
Byte | Da 0 a 255; le frazioni vengono arrotondate. | |
Carattere | Qualsiasi espressione String valida; il valore può essere compreso tra 0 e 65 535. | |
Data | Qualsiasi rappresentazione valida della data e dell'ora. | |
Double | da -1,79769313486231E+308 a -4,94065645841247E-324 per i valori negativi; da 4,94065645841247E-324 a 1,79769313486231E+308 per i valori positivi. | |
Decimale | +/-79 228 162 514 264 337 593 543 950 335 per i numeri senza decimali. L’intervallo di valori dei numeri a 28 cifre decimali è +/-7,9228162514264337593543950335. Il numero più piccolo diverso da zero è 0,0000000000000000000000000001. | |
Intero | da -2 147 483 648 a 2 147 483 647; le frazioni vengono arrotondate. | |
Numero lungo | da -9 223 372 036 854 775 808 a 9 223 372 036 854 775 807; le frazioni vengono arrotondate. | |
| Oggetto | Qualsiasi espressione valida. |
Short | Da -32 768 a 32 767; le frazioni vengono arrotondate. | |
Singolo | da -3,402823E+38 a -1,401298E-45 per i valori negativi; da 1,401298E-45 a 3,402823E+38 per i valori positivi. | |
String | I valori restituiti dalla funzione Cstr dipendono dall'argomento expression. |
Ecco un programma di esempio:
Module conversion
Sub main()
Dim var1 As Boolean = CBool("true")
Dim var2 As Byte = CByte("100")
Dim var3 As Char = CChar("A")
Dim var4 As Date = CDate("30 janvier 2004")
Dim var5 As Double = CDbl("100,45")
Dim var6 As Decimal = CDec("1000,67")
Dim var7 As Integer = CInt("-30")
Dim var8 As Long = CLng("456")
Dim var9 As Short = CShort("-14")
Dim var10 As Single = CSng("56,78")
Console.Out.WriteLine("var1=" & var1)
Console.Out.WriteLine("var2=" & var2)
Console.Out.WriteLine("var3=" & var3)
Console.Out.WriteLine("var4=" & var4)
Console.Out.WriteLine("var5=" & var5)
Console.Out.WriteLine("var6=" & var6)
Console.Out.WriteLine("var7=" & var7)
Console.Out.WriteLine("var8=" & var8)
Console.Out.WriteLine("var9=" & var9)
Console.Out.WriteLine("var10=" & var10)
End Sub
End Module
e i risultati della sua esecuzione:
var1=True
var2=100
var3=A
var4=30/01/2004
var5=100,45
var6=1000,67
var7=-30
var8=456
var9=-14
var10=56,78
È inoltre possibile utilizzare la funzione CType(expression, type) come illustrato nel seguente programma:
Module ctype1
Sub main()
Dim var1 As Boolean = CType("true", Boolean)
Dim var2 As Byte = CType("100", Byte)
Dim var3 As Char = CType("A", Char)
Dim var4 As Date = CType("30 janvier 2004", Date)
Dim var5 As Double = CType("100,45", Double)
Dim var6 As Decimal = CType("1000,67", Decimal)
Dim var7 As Integer = CType("-30", Integer)
Dim var8 As Long = CType("456", Long)
Dim var9 As Short = CType("-14", Short)
Dim var10 As Single = CType("56,78", Single)
Dim var11 As String = CType("47,89", String)
Dim var12 As String = 47.89.ToString
Dim var13 As String = "" & 47.89
Console.Out.WriteLine("var1=" & var1)
Console.Out.WriteLine("var2=" & var2)
Console.Out.WriteLine("var3=" & var3)
Console.Out.WriteLine("var4=" & var4)
Console.Out.WriteLine("var5=" & var5)
Console.Out.WriteLine("var6=" & var6)
Console.Out.WriteLine("var7=" & var7)
Console.Out.WriteLine("var8=" & var8)
Console.Out.WriteLine("var9=" & var9)
Console.Out.WriteLine("var10=" & var10)
Console.Out.WriteLine("var11=" & var11)
Console.Out.WriteLine("var12=" & var12)
Console.Out.WriteLine("var13=" & var13)
End Sub
End Module
che fornisce i seguenti risultati:
var1=True
var2=100
var3=A
var4=30/01/2004
var5=100,45
var6=1000,67
var7=-30
var8=456
var9=-14
var10=56,78
var11=47,89
var12=47,89
var13=47,89
2.4. Istruzioni per il controllo dello svolgimento del programma
2.4.1. Arresto
Il metodo Exit definito nella classe Environment consente di interrompere l'esecuzione di un programma:
[Visual Basic]
Public Shared Sub Exit(ByVal exitCode As Integer )
interrompe il processo in corso e restituisce il valore exitCode al processo padre. Quest'ultimo può utilizzare il valore di exitCode. Con DOS, questa variabile di stato viene restituita a DOS nella variabile di sistema ERRORLEVEL, il cui valore può essere verificato in un file batch. In Unix, è la variabile $? che recupera il valore di exitCode.
interromperà l'esecuzione del programma con un valore di stato pari a 0.
2.4.2. Struttura di selezione semplice
- ogni azione è su una riga
- la clausola else può essere assente.
È possibile annidare le strutture di selezione, come mostra il seguente esempio:
' opzioni
Option Explicit On
Option Strict On
' spazi dei nomi
Imports System
Module if1
Sub main()
Dim i As Integer = 10
If i > 4 Then
Console.Out.WriteLine(i & " est > " & 4)
Else
If i = 4 Then
Console.Out.WriteLine(i & " est = " & 4)
Else
Console.Out.WriteLine(i & " est < " & 4)
End If
End If
End Sub
End Module
Il risultato ottenuto:
2.4.3. Struttura dei casi
La sintassi è la seguente:
select case expression
case liste_valeurs1
actions1
case liste_valeurs2
actions2
...
case else
actions_sinon
end select
- Il tipo di [expression] deve essere uno dei seguenti:
- la clausola [case else] può essere assente.
- [liste_valeursi] sono valori possibili dell'espressione. [listes_valeursi] rappresenta un elenco di condizioni: condizione1, condizione2, ..., condizionex. Se [expression] soddisfa una delle condizioni, vengono eseguite le azioni associate alla clausola [liste_valeursi]. Le condizioni possono assumere la seguente forma:
- val1 to val2: vero se [expression] appartiene al dominio [val1,val2]
- val1: vero se [expression] è uguale a val1
- is > val1: vero se [expression] > val1. La parola chiave [is] può essere omessa
- lo stesso vale per gli operatori =, <, <=, >, >=, <>
- vengono eseguite solo le azioni relative alla prima condizione verificata.
Consideriamo il seguente programma:
' opzioni
Option Explicit On
Option Strict On
' spazi dei nomi
Imports System
Module selectcase1
Sub main()
Dim i As Integer = 10
Select Case i
Case 1 To 4, 7 To 8
Console.Out.WriteLine("i est dans l'intervalle [1,4] ou [7,8]")
Case Is > 12
Console.Out.WriteLine("i est > 12")
Case Is < 15
Console.Out.WriteLine("i est < 15")
Case Is < 20
Console.Out.WriteLine("i est < 20")
End Select
End Sub
End Module
Fornisce i seguenti risultati:
2.4.4. Struttura di ripetizione
2.4.4.1. Numero di ripetizioni noto
For counter [ As datatype ] = start To end [ Step step ]
actions
Next [ counter ]
Le operazioni vengono eseguite per ciascuno dei valori assunti dalla variabile [counter]. Consideriamo il seguente programma:
' opzioni
Option Explicit On
Option Strict On
' spazi dei nomi
Imports System
Module for1
Sub main()
Dim somme As Integer = 0
Dim résultat As String = "somme("
For i As Integer = 0 To 10 Step 2
somme += i
résultat += " " + i.ToString
Next
résultat += ")=" + somme.ToString
Console.Out.WriteLine(résultat)
End Sub
End Module
I risultati:
Un'altra struttura di iterazione con numero di iterazioni noto è la seguente:
For Each element [ As datatype ] In groupe
[ actions ]
Next [ element ]
- groupe è una collezione di oggetti. La collezione di oggetti che già conosciamo è l'array
- datatype è il tipo degli oggetti della collezione. Per un array, sarebbe il tipo degli elementi dell’array
- element è una variabile locale al ciclo che assumerà in successione, come valore, tutti i valori della collezione.
Pertanto, il codice seguente:
' opzioni
Option Explicit On
Option Strict On
' spazi dei nomi
Imports System
Module foreach1
Sub main()
Dim amis() As String = {"paul", "hélène", "jacques", "sylvie"}
For Each nom As String In amis
Console.Out.WriteLine(nom)
Next
End Sub
End Module
visualizzerebbe:
2.4.4.2. Numero di ripetizioni sconosciuto
Esistono numerose strutture in VB.NET per questo caso.
Do { While | Until } condition
[ statements ]
Loop
Il ciclo continua finché la condizione è vera (while) o fino a quando la condizione è vera (until). Il ciclo potrebbe non essere mai eseguito.
Do
[ statements ]
Loop { While | Until } condition
Il ciclo continua finché la condizione è vera (while) o fino a quando la condizione diventa vera (until). Il ciclo viene sempre eseguito almeno una volta.
While condition
[ statements ]
End While
Il ciclo continua finché la condizione è vera. Il ciclo potrebbe non essere mai eseguito. I cicli seguenti calcolano tutti la somma dei primi 10 numeri interi.
' opzioni
Option Explicit On
Option Strict On
' spazi dei nomi
Imports System
Module boucles1
Sub main()
Dim i, somme As Integer
i = 0 : somme = 0
Do While i < 11
somme += i
i += 1
Loop
Console.Out.WriteLine("somme=" + somme.ToString)
i = 0 : somme = 0
Do Until i = 11
somme += i
i += 1
Loop
Console.Out.WriteLine("somme=" + somme.ToString)
i = 0 : somme = 0
Do
somme += i
i += 1
Loop Until i = 11
Console.Out.WriteLine("somme=" + somme.ToString)
i = 0 : somme = 0
Do
somme += i
i += 1
Loop While i < 11
Console.Out.WriteLine("somme=" + somme.ToString)
End Sub
End Module
2.4.4.3. Istruzioni per la gestione dei cicli
esce da un ciclo do ... loop | |
esce da un ciclo for |
2.5. La struttura di un programma VB.NET
Un programma VB.NET che non utilizza classi definite dall'utente né funzioni diverse dalla funzione principale Main potrà avere la seguente struttura:
' opzioni
Option Explicit On
Option Strict On
' spazi dei nomi
Imports espace1
Imports ....
Module nomDuModule
Sub main()
....
End Sub
End Module
- La direttiva [Option Explicit on] impone la dichiarazione delle variabili. In VB.NET, invece, la dichiarazione non è obbligatoria. Una variabile non dichiarata è quindi di tipo Object.
- La direttiva [Option Strict on] vieta qualsiasi conversione di tipi di dati che possa comportare una perdita di dati e qualsiasi conversione tra tipi numerici e stringhe. È quindi necessario utilizzare esplicitamente le funzioni di conversione.
- Il programma importa tutti gli spazi dei nomi di cui ha bisogno. Non abbiamo ancora introdotto questo concetto. Nei programmi precedenti abbiamo spesso incontrato istruzioni del tipo:
In realtà avremmo dovuto scrivere:
dove System è lo spazio dei nomi contenente la classe [Console]. Importando lo spazio dei nomi [System] con un'istruzione Imports, VB.NET lo esplorerà sistematicamente ogni volta che incontrerà una classe che non conosce. Ripeterà la ricerca in tutti gli spazi dei nomi dichiarati fino a trovare la classe ricercata. Si scrive quindi:
' spazi dei nomi
Imports System
....
Console.Out.WriteLine(unechaine)
Un esempio di programma potrebbe essere il seguente:
' opzioni
Option Explicit On
Option Strict On
'spazi dei nomi
Imports System
' modulo principale
Module main1
Sub main()
Console.Out.WriteLine("main1")
End Sub
End Module
Lo stesso programma può essere scritto nel modo seguente:
' opzioni
Option Explicit On
Option Strict On
'spazi dei nomi
Imports System
' classe di test
Public Class main2
Public Shared Sub main()
Console.Out.WriteLine("main2")
End Sub
End Class
Qui utilizziamo il concetto di classe che verrà introdotto nel capitolo successivo. Quando una classe di questo tipo contiene una procedura statica (shared) denominata main, questa viene eseguita. Se introduciamo questa sintassi qui, è perché il linguaggio gemello di VB.NET, ovvero C#, conosce solo il concetto di classe, c.a.d, per cui ogni codice eseguito appartiene necessariamente a una classe. Il concetto di classe appartiene alla programmazione orientata agli oggetti. Imporlo nella progettazione di ogni programma è un po’ inopportuno. Lo si vede qui nella versione 2 del programma precedente, dove si è costretti a introdurre il concetto di classe e di metodo statico laddove non ce n’è bisogno. Pertanto, d’ora in poi, introdurremo il concetto di classe solo quando sarà necessario. Negli altri casi, utilizzeremo il concetto di modulo come nella versione 1 sopra riportata.
2.6. Compilazione ed esecuzione di un programma VB.NET
La compilazione di un programma VB.NET richiede solo il SDK.NET. Prendiamo il seguente programma:
' opzioni
Option Explicit On
Option Strict On
' spazi dei nomi
Imports System
Module boucles1
Sub main()
Dim i, somme As Integer
i = 0 : somme = 0
Do While i < 11
somme += i
i += 1
Loop
Console.Out.WriteLine("somme=" + somme.ToString)
i = 0 : somme = 0
Do Until i = 11
somme += i
i += 1
Loop
Console.Out.WriteLine("somme=" + somme.ToString)
i = 0 : somme = 0
Do
somme += i
i += 1
Loop Until i = 11
Console.Out.WriteLine("somme=" + somme.ToString)
i = 0 : somme = 0
Do
somme += i
i += 1
Loop While i < 11
Console.Out.WriteLine("somme=" + somme.ToString)
End Sub
End Module
Supponiamo che si trovi in un file denominato [boucles1.vb]. Per compilarlo, procediamo come segue:
dos>dir boucles1.vb
11/03/2004 15:55 583 boucles1.vb
dos>vbc boucles1.vb
Compilateur Microsoft (R) Visual Basic .NET version 7.10.3052.4
pour Microsoft (R) .NET Framework version 1.1.4322.573
Copyright (C) Microsoft Corporation 1987-2002. Tous droits réservés.
dos>dir boucles1.*
11/03/2004 16:04 601 boucles1.vb
11/03/2004 16:04 3 584 boucles1.exe
Il programma vbc.exe è il compilatore VB.NET. Qui era presente nel PATH del DOS:
dos>path
PATH=E:\Program Files\Microsoft Visual Studio .NET 2003\Common7\IDE;E:\Program Files\Microsoft Visual Studio .NET 2003\VC7\BIN;E:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Tools;E:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Tools\bin\prerelease;E:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Tools\bin;E:\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1\bin;E:\WINNT\Microsoft.NET\Framework\v1.1.4322;e:\winnt\system32;e:\winnt;
dos>dir E:\WINNT\Microsoft.NET\Framework\v1.1.4322\vbc.exe
21/02/2003 10:20 737 280 vbc.exe
Il compilatore [vbc] genera un file .exe eseguibile dalla macchina virtuale .NET:
2.7. L'esempio IMPOTS
Si propone di scrivere un programma che consenta di calcolare l'imposta di un contribuente. Si considera il caso semplificato di un contribuente che abbia da dichiarare solo il proprio stipendio:
- si calcola il numero di quote del dipendente nbParts=nbEnfants/2 +1 se non è sposato, nbEnfants/2+2 se è sposato, dove nbEnfants è il numero dei suoi figli.
- se ha almeno tre figli, ha diritto a una mezza quota in più
- si calcola il suo reddito imponibile R = 0,72 * S, dove S è il suo stipendio annuale
- si calcola il suo coefficiente familiare QF = R / nbParts
- si calcola la sua imposta I. Consideriamo la seguente tabella:
12620,0 | 0 | 0 |
13190 | 0,05 | 631 |
15640 | 0,1 | 1290,5 |
24.740 | 0,15 | 2072,5 |
31810 | 0,2 | 3309,5 |
39.970 | 0,25 | 4900 |
48360 | 0,3 | 6898,5 |
55790 | 0,35 | 9316,5 |
92970 | 0,4 | 12106 |
127.860 | 0,45 | 16754,5 |
151250 | 0,50 | 23.147,5 |
172.040 | 0,55 | 30710 |
195.000 | 0,60 | 39312 |
0 | 0,65 | 49062 |
Ogni riga ha 3 campi. Per calcolare l'imposta I, si cerca la prima riga in cui QF<=campo1. Ad esempio, se QF=23000, si troverà la riga
L'imposta I è quindi pari a 0,15*R - 2072,5*nbParts. Se QF è tale che la relazione QF<=campo1 non è mai soddisfatta, allora vengono utilizzati i coefficienti dell’ultima riga. In questo caso:
il che dà come risultato l’imposta I=0,65*R - 49062*nbParts. Il programma VB.NET corrispondente è il seguente:
' opzioni
Option Explicit On
Option Strict On
' spazi dei nomi
Imports System
Module impots
' ------------ main
Sub Main()
' tabelle di dati necessarie per il calcolo dell'imposta
Dim Limites() As Decimal = {12620D, 13190D, 15640D, 24740D, 31810D, 39970D, 48360D, 55790D, 92970D, 127860D, 151250D, 172040D, 195000D, 0D}
Dim CoeffN() As Decimal = {0D, 631D, 1290.5D, 2072.5D, 3309.5D, 4900D, 6898.5D, 9316.5D, 12106D, 16754.5D, 23147.5D, 30710D, 39312D, 49062D}
' si recupera lo stato civile
Dim OK As Boolean = False
Dim reponse As String = Nothing
While Not OK
Console.Out.Write("Etes-vous marié(e) (O/N) ? ")
reponse = Console.In.ReadLine().Trim().ToLower()
If reponse <> "o" And reponse <> "n" Then
Console.Error.WriteLine("Réponse incorrecte. Recommencez")
Else
OK = True
End If
End While
Dim Marie As Boolean = reponse = "o"
' numero di figli
OK = False
Dim NbEnfants As Integer = 0
While Not OK
Console.Out.Write("Nombre d'enfants : ")
reponse = Console.In.ReadLine()
Try
NbEnfants = Integer.Parse(reponse)
If NbEnfants >= 0 Then
OK = True
Else
Console.Error.WriteLine("Réponse incorrecte. Recommencez")
End If
Catch
Console.Error.WriteLine("Réponse incorrecte. Recommencez")
End Try
End While
' stipendio
OK = False
Dim Salaire As Integer = 0
While Not OK
Console.Out.Write("Salaire annuel : ")
reponse = Console.In.ReadLine()
Try
Salaire = Integer.Parse(reponse)
If Salaire >= 0 Then
OK = True
Else
Console.Error.WriteLine("Réponse incorrecte. Recommencez")
End If
Catch
Console.Error.WriteLine("Réponse incorrecte. Recommencez")
End Try
End While
' calcolo del numero di quote
Dim NbParts As Decimal
If Marie Then
NbParts = CDec(NbEnfants) / 2 + 2
Else
NbParts = CDec(NbEnfants) / 2 + 1
End If
If NbEnfants >= 3 Then
NbParts += 0.5D
End If
' reddito imponibile
Dim Revenu As Decimal
Revenu = 0.72D * Salaire
' quoziente familiare
Dim QF As Decimal
QF = Revenu / NbParts
' ricerca della fascia di imposta corrispondente a QF
Dim i As Integer
Dim NbTranches As Integer = Limites.Length
Limites((NbTranches - 1)) = QF
i = 0
While QF > Limites(i)
i += 1
End While
' l'imposta
Dim impots As Integer = CInt(i * 0.05D * Revenu - CoeffN(i) * NbParts)
' viene visualizzato il risultato
Console.Out.WriteLine(("Impôt à payer : " & impots))
End Sub
End Module
Il programma viene compilato in una finestra DOS con:
dos>vbc impots1.vb
Compilateur Microsoft (R) Visual Basic .NET version 7.10.3052.4 pour Microsoft (R) .NET Framework version 1.1.4322.573
dos>dir impots1.exe
24/02/2004 15:42 5 632 impots1.exe
La compilazione produce un eseguibile impots.exe. Va notato che impots.exe non è direttamente eseguibile dal processore. Contiene infatti codice intermedio eseguibile solo su una piattaforma .NET. I risultati ottenuti sono i seguenti:
dos>impots1
Etes-vous marié(e) (O/N) ? o
Nombre d'enfants : 3
Salaire annuel : 200000
Impôt à payer : 16400
dos>impots1
Etes-vous marié(e) (O/N) ? n
Nombre d'enfants : 2
Salaire annuel : 200000
Impôt à payer : 33388
dos>impots1
Etes-vous marié(e) (O/N) ? w
Réponse incorrecte. Recommencez
Etes-vous marié(e) (O/N) ? q
Réponse incorrecte. Recommencez
Etes-vous marié(e) (O/N) ? o
Nombre d'enfants : q
Réponse incorrecte. Recommencez
Nombre d'enfants : 2
Salaire annuel : q
Réponse incorrecte. Recommencez
Salaire annuel : 1
Impôt à payer : 0
2.8. Argomenti del programma principale
La procedura principale Main può accettare come parametro un array di stringhe:
Sub main(ByVal args() As String)
Il parametro args è un array di stringhe che riceve gli argomenti passati dalla riga di comando al momento della chiamata del programma.
- args.Length è il numero di elementi dell'array args
- args(i) è l'elemento i dell'array
Se si avvia il programma P con il comando: P arg0 arg1 … argn e se la procedura Main del programma P è dichiarata come segue:
Sub main(ByVal args() As String)
si avrà arg(0)="arg0", arg(1)="arg1" … Ecco un esempio:
' linee guida
Option Strict On
Option Explicit On
' spazi dei nomi
Imports System
Module arg
Sub main(ByVal args() As String)
' numero di argomenti
console.out.writeline("Il y a " & args.length & " arguments")
Dim i As Integer
For i = 0 To args.Length - 1
Console.Out.WriteLine("argument n° " & i & "=" & args(i))
Next
End Sub
End Module
L'esecuzione fornisce i seguenti risultati:
2.9. Le enumerazioni
Un'enumerazione è un tipo di dati il cui dominio di valori è un insieme di costanti intere. Consideriamo un programma che deve gestire i voti di un esame. Ce ne sarebbero cinque: Discreto, AssezBien, Buono, TrèsBien, Eccellente. Si potrebbe quindi definire un'enumerazione per queste cinque costanti:
Enum mention
Passable
AssezBien
Bien
TrésBien
Excellent
End Enum
Internamente, queste cinque costanti sono codificate da numeri interi consecutivi che iniziano con 0 per la prima costante, 1 per la successiva e così via. Una variabile può essere dichiarata in modo da assumere questi valori nell'enumerazione:
' una variabile che assume i propri valori dall'enumerazione menzionata
Dim maMention As mention = mention.Passable
È possibile confrontare una variabile con i diversi valori possibili dell'enumerazione:
' test con valore dell'enumerazione
If (maMention = mention.Passable) Then
Console.Out.WriteLine("Peut mieux faire")
End If
È possibile ottenere tutti i valori dell'enumerazione:
For Each m In mention.GetValues(maMention.GetType)
Console.Out.WriteLine(m)
Next
Allo stesso modo in cui il tipo semplice Integer è equivalente alla struttura Int32, il tipo semplice Enum è equivalente alla struttura Enum. Questa classe dispone di un metodo statico GetValues che consente di ottenere tutti i valori di un tipo enumerato passato come parametro. Quest’ultimo deve essere un oggetto di tipo Type, ovvero una classe che fornisce informazioni sul tipo di un dato. Il tipo di una variabile v si ottiene tramite v.GetType(). Quindi, in questo caso, maMention.GetType() restituisce l’oggetto Type dell’enumerazione mentions e Enum.GetValues(maMention.GetType()) l'elenco dei valori dell'enumerazione mentions.
Questo è quanto illustra il seguente programma:
' direttive
Option Strict On
Option Explicit On
' spazi dei nomi
Imports System
Public Module enum2
' un'enumerazione
Enum mention
Passable
AssezBien
Bien
TrèsBien
Excellent
End Enum
' pagina di test
Sub Main()
' una variabile che assume i propri valori dall'enumerazione menzionata
Dim maMention As mention = mention.Passable
' visualizzazione del valore della variabile
Console.Out.WriteLine("mention=" & maMention)
' test con valore dell'enumerazione
If (maMention = mention.Passable) Then
Console.Out.WriteLine("Peut mieux faire")
End If
' elenco delle voci letterali
For Each m As mention In [Enum].GetValues(maMention.GetType)
Console.Out.WriteLine(m.ToString)
Next
' elenco delle menzioni intere
For Each m As Integer In [Enum].GetValues(maMention.GetType)
Console.Out.WriteLine(m)
Next
End Sub
End Module
I risultati dell'esecuzione sono i seguenti:
2.10. Gestione delle eccezioni
Numerose funzioni VB.NET possono generare eccezioni, ovvero errori. Quando una funzione è suscettibile di generare un'eccezione, il programmatore dovrebbe gestirla al fine di ottenere programmi più resistenti agli errori: occorre sempre evitare il "blocco" improvviso di un'applicazione.
La gestione di un'eccezione avviene secondo lo schema seguente:
try
appel de la fonction susceptible de générer l'exception
catch e as Exception e)
traiter l'exception e
end try
instruction suivante
Se la funzione non genera un'eccezione, si passa all'istruzione successiva; in caso contrario, si passa al corpo della clausola catch e poi all'istruzione successiva. Si notino i seguenti punti:
- e è un oggetto derivato dal tipo Exception. È possibile essere più precisi utilizzando tipi quali IOException, SystemException, ecc.: esistono infatti diversi tipi di eccezioni. Scrivendo `catch e as Exception`, si indica che si desidera gestire tutti i tipi di eccezioni. Se il codice della clausola `try` è suscettibile di generare diversi tipi di eccezioni, si può voler essere più precisi gestendo l’eccezione con più clausole `catch`:
try
appel de la fonction susceptible de générer l'exception
catch e as IOException
traiter l'exception e
catch e as SystemException
traiter l'exception e
end try
instruction suivante
- È possibile aggiungere una clausola finally alle clausole try/catch:
try
appel de la fonction susceptible de générer l'exception
catch e as Exception
traiter l'exception e
finally
code exécuté après try ou catch
end try
instruction suivante
Che vi sia o meno un'eccezione, il codice della clausola finally verrà sempre eseguito.
- Nella clausola catch, potrebbe non essere opportuno utilizzare l'oggetto Exception disponibile. Invece di scrivere `catch e as Exception`, si scriverà quindi `catch`.
- La classe Exception ha una proprietà Message che contiene un messaggio che descrive in dettaglio l’errore verificatosi. Pertanto, se si desidera visualizzarlo, si scriverà:
catch e as Exception
Console.Error.WriteLine("L'erreur suivante s'est produite : "+e.Message);
...
end try
- La classe Exception dispone di un metodo ToString che restituisce una stringa di caratteri indicante il tipo dell’eccezione e il valore della proprietà Message. Si potrà quindi scrivere:
catch ex as Exception
Console.Error.WriteLine("L'erreur suivante s'est produite : "+ex.ToString)
...
end try
L'esempio seguente mostra un'eccezione generata dall'utilizzo di un elemento di array inesistente:
' opzioni
Option Explicit On
Option Strict On
' spazi dei nomi
Imports System
Module tab1
Sub Main()
' dichiarazione e inizializzazione di un array
Dim tab() As Integer = {0, 1, 2, 3}
Dim i As Integer
' visualizzazione di un array con un ciclo for
For i = 0 To tab.Length - 1
Console.Out.WriteLine(("tab[" & i & "]=" & tab(i)))
Next i
' visualizzazione di un array con un ciclo for each
Dim élmt As Integer
For Each élmt In tab
Console.Out.WriteLine(élmt)
Next élmt
' Generazione di un'eccezione
Try
tab(100) = 6
Catch e As Exception
Console.Error.WriteLine(("L'erreur suivante s'est produite : " & e.Message))
End Try
End Sub
End Module
L'esecuzione del programma produce i seguenti risultati:
dos>exception1
tab[0]=0
tab[1]=1
tab[2]=2
tab[3]=3
0
1
2
3
L'erreur suivante s'est produite : L'index se trouve en dehors des limites du tableau.
Ecco un altro esempio in cui si gestisce l'eccezione causata dall'assegnazione di una stringa di caratteri a un numero quando la stringa non rappresenta un numero:
' opzioni
Option Strict On
Option Explicit On
'importazioni
Imports System
Public Module console1
Public Sub Main()
' Viene richiesto il nome
System.Console.Write("Nom : ")
' lettura della risposta
Dim nom As String = System.Console.ReadLine()
' viene richiesta l'età
Dim age As Integer
Dim ageOK As Boolean = False
Do While Not ageOK
' domanda
Console.Out.Write("âge : ")
' Lettura e verifica della risposta
Try
age = Int32.Parse(System.Console.ReadLine())
If age < 0 Then Throw New Exception
ageOK = True
Catch
Console.Error.WriteLine("Age incorrect, recommencez...")
End Try
Loop
' visualizzazione finale
Console.Out.WriteLine("Vous vous appelez [" & nom & "] et vous avez [" & age & "] ans")
End Sub
End Module
Alcuni risultati dell'esecuzione:
dos>console1
Nom : dupont
âge : xx
Age incorrect, recommencez...
âge : 12
Vous vous appelez dupont et vous avez 12 ans
2.11. Passaggio dei parametri a una funzione
In questa sede ci occuperemo delle modalità di passaggio dei parametri a una funzione. Consideriamo la funzione:
Sub changeInt(ByVal a As Integer)
a = 30
Console.Out.WriteLine(("Paramètre formel a=" & a))
End Sub
Nella definizione della funzione, a è definito come parametro formale. È presente solo ai fini della definizione della funzione changeInt. Avrebbe potuto benissimo chiamarsi b. Consideriamo ora un utilizzo di questa funzione:
Sub Main()
Dim age As Integer = 20
changeInt(age)
Console.Out.WriteLine(("Paramètre effectif age=" & age))
End Sub
Qui, nell'istruzione changeInt(età), age è il parametro effettivo che trasmetterà il proprio valore al parametro formale a. Ci interessa capire in che modo un parametro formale recuperi il valore del parametro effettivo a cui corrisponde.
2.11.1. Passaggio per valore
L'esempio seguente mostra che i parametri di una funzione/procedura vengono passati per impostazione predefinita per valore: ciò significa che il valore del parametro effettivo viene copiato nel parametro formale corrispondente. Si tratta di due entità distinte. Se la funzione modifica il parametro formale, il parametro effettivo non subisce alcuna modifica.
' opzioni
Option Explicit On
Option Strict On
' passaggio di parametri per valore a una funzione
Imports System
Module param1
Sub Main()
Dim age As Integer = 20
changeInt(age)
Console.Out.WriteLine(("Paramètre effectif age=" & age))
End Sub
Sub changeInt(ByVal a As Integer)
a = 30
Console.Out.WriteLine(("Paramètre formel a=" & a))
End Sub
End Module
I risultati ottenuti sono i seguenti:
Il valore 20 del parametro effettivo è stato copiato nel parametro formale a. Quest'ultimo è stato poi modificato. Il parametro effettivo è rimasto invece invariato. Questa modalità di passaggio è adatta ai parametri di ingresso di una funzione.
2.11.2. Passaggio per riferimento
Nel passaggio per riferimento, il parametro effettivo e il parametro formale sono la stessa entità. Se la funzione modifica il parametro formale, anche il parametro effettivo viene modificato. In VB.NET, il parametro formale deve essere preceduto dalla parola chiave ByRef. Ecco un esempio:
' opzioni
Option Explicit On
Option Strict On
' passaggio di parametri per valore a una funzione
Imports System
Module param2
Sub Main()
Dim age As Integer = 20
changeInt(age)
Console.Out.WriteLine(("Paramètre effectif age=" & age))
End Sub
Sub changeInt(ByRef a As Integer)
a = 30
Console.Out.WriteLine(("Paramètre formel a=" & a))
End Sub
End Module
e i risultati dell’esecuzione:
Il parametro effettivo ha seguito la modifica del parametro formale. Questa modalità di passaggio è adatta ai parametri di output di una funzione.

