Skip to content

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:

  1. numeri interi, reali e decimali
  2. caratteri e stringhe di caratteri
  3. i valori booleani
  4. le date
  5. 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

Integer
145, -7, &FF (esadecimale)
Long
100000L
Double
134,789, -45E-18 (-45 × 10⁻¹⁸)
Single
134.789F, -45E-18F (-45 10⁻¹⁸)
Decimal
100000D
Char
"A"c
String
"oggi"
Boolean
vero, falso
date
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?

  1. La lettura del programma risulterà più agevole se alla costante viene assegnato un nome significativo: [const taux_tva as single=0.186F]
  2. 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 -> chaîne
nombre.ToString oppure "" & numero oppure CType(numero,String)
objet -> chaîne
objet.ToString
chaine -> Integer
Integer.Parse(stringa) oppure Int32.Parse
chaîne -> Long
Long.Parse (stringa) o Int64.Parse
chaîne -> Double
Double.Parse (stringa)
chaîne -> Single
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.

  1. lettura delle informazioni provenienti dalla tastiera

  2. elaborazione delle informazioni

  3. scrittura di informazioni sullo schermo

  4. lettura delle informazioni da un file su disco

  5. 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:

System.Object
i=10
Tapez une ligne : ceci est un essai
ligne=ceci est un essai

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:

  1. periferica di ingresso standard - indica per impostazione predefinita la tastiera e porta il n. 0
  2. periferica di uscita standard - indica per impostazione predefinita lo schermo e ha il numero 1
  3. 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:

pg arg1 arg2 .. argn

Utilizzando gli argomenti argi del programma pg, è possibile reindirizzare le periferiche di I/O standard verso dei file:

0<in.txt
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.
 
1>out.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
  
1>>out.txt
idem, ma i dati scritti vengono aggiunti al contenuto attuale del file out.txt.
  
2>error.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
  
2>>error.txt
idem, ma i dati scritti vengono aggiunti al contenuto attuale del file error.txt.
  
1>out.txt 2>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

dos>es2.exe 0<in.txt 1>out.txt 2>error.txt

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
Arithmétique
^, –, *, /, \, Mod, +, =
Assignation
=, ^=, *=, /=, \=, +=, -=, &=
Comparaison
=, <>, <, >, <=, >=, Like, Is
Concaténation
&, +
Opérations logiques/de bits
Not, And, Or, Xor, AndAlso, OrElse
Opérations diverses
AddressOf, GetType

2.3.5.2. Espressione aritmetica

Gli operatori delle espressioni aritmetiche sono i seguenti:

Arithmétique
^, –, *, /, \, 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:

4/3=1,33333333333333
4\3=1
4 mod 3=1
4,1/3,6=1,13888888888889
4,1^2=16,81
-0,989992496600445

Esistono diverse funzioni matematiche. Eccone alcune:


Public Shared Function Sqrt(ByVal d As Double ) As Double
radice quadrata

[Visual Basic]
Public Shared Function Cos(ByVal d As Double ) As Double
Coseno

Public Shared Function Sin(ByVal a As Double) As Double
Sen

[Visual Basic]
Public Shared Function Tan(ByVal a As Double) As Double
Tangente

[Visual Basic]
Public Shared Function Pow(ByVal x As Double,ByVal y As Double) As Double
x alla potenza y (x>0)

[Visual Basic]
Public Shared Function Exp(ByVal d As Double) As Double
Esponenziale

[Visual Basic]
Overloads Public Shared Function Log( ByVal d As Double ) As Double
Logaritmo naturale

Overloads Public Shared Function Abs(ByVal value As Double ) As Double
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à:

        Dim r1, r2 As Double
        r2 = Math.Sqrt(9)
        r1 = Math.Cos(3)

La definizione completa della classe Math è la seguente:

E 
Rappresenta la base del logaritmo naturale specificata dalla costante e.
  
PI 
Rappresenta il rapporto tra la circonferenza di un cerchio e il suo diametro, specificato dalla costante π.
  
Abs 
Sovraccaricato. Restituisce il valore assoluto di un numero specificato.
 
Acos 
Restituisce l'angolo il cui coseno è il numero specificato.
 
Asin 
Restituisce l'angolo il cui seno è il numero specificato.
 
Atan 
Restituisce l'angolo la cui tangente è il numero specificato.
 
Atan2 
Restituisce l'angolo la cui tangente è il quoziente di due numeri specificati.
 
BigMul
Genera il prodotto intero di due numeri a 32 bit.
 
Ceiling 
Restituisce il numero intero più piccolo maggiore o uguale al numero specificato.
 
Cos 
Restituisce il coseno dell'angolo specificato.
 
Cosh 
Restituisce il coseno iperbolico dell'angolo specificato.
 
DivRem
Sovraccaricato. Restituisce il quoziente di due numeri, passando il resto come parametro di output.
 
Exp 
Restituisce e elevato alla potenza specificata.
 
Floor 
Restituisce il numero intero più grande minore o uguale al numero specificato.
 
IEEERemainder 
Restituisce il resto della divisione di un numero specificato per un altro.
 
Log 
Sovraccaricato. Restituisce il logaritmo di un numero specificato.
 
Log10 
Restituisce il logaritmo in base 10 di un numero specificato.
 
Max 
Sovraccaricato. Restituisce il più grande tra due numeri specificati.
 
Min 
Sovraccaricato. Restituisce il più piccolo tra due numeri.
 
Pow 
Restituisce un numero specificato elevato alla potenza specificata.
 
Round 
Sovraccaricato. Restituisce il numero più vicino al valore specificato.
 
Sign 
Sovraccaricato. Restituisce un valore che indica il segno di un numero.
 
Sin 
Restituisce il seno dell'angolo specificato.
 
Sinh 
Restituisce il seno iperbolico dell'angolo specificato.
 
Sqrt 
Restituisce la radice quadrata di un numero specificato.
 
Tan 
Restituisce la tangente dell'angolo specificato.
 
Tanh 
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
Primaire
Tutte le espressioni senza operatori: funzioni, parentesi
Élévation à la puissance
^
Négation unaire
+, -
Multiplication
*, /
Division par un entier
\
Modulo
Mod
Addition
+, -

2.3.5.4. Espressioni relazionali

Gli operatori sono i seguenti:

Comparaison
=, <>, <, >, <=, >=, 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:

A<B=True
A<a=True
chat<chien=True
chat<chaton=True
chat<CHAT=False
chaton like chat*=True

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:

Opérations logiques/de bits
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 logique
Not
AND logique
And, AndAlso
OR logique
Oppure, OrElse
XOR logique
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.

i<<n
sposta i di n bit a sinistra. I bit che entrano sono zeri.
i>>n
sposta i di n bit a destra. Se i è un numero intero con segno (signed char, int, long), il bit di segno viene mantenuto.
i & j
esegue l'OR logico bit per bit tra i e j.
i | j
esegue la logica bit per bit tra i e j (OU).
~i
imposta i a 1
i^j
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:

i<<4=23F0
i>>4=123
k>>4=712
i and 4=4
i or k =123F
not i=EDC0

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:

combinaison d'opérateurs
^=, *=, /=, \=, +=, -=, &=

2.3.5.8. Priorità generale degli operatori

Categoria
Operatori
Primaire
Tutte le espressioni senza operatore
Élévation à la puissance
^
Négation unaire
+, -
Multiplication
*, /
Division par un entier
\
Modulo
Mod
Addition
+, -
Concaténation
&
Déplacement
<<, >>
Relationnel
=, <>, <, >, <=, >=, Like, Is, TypeOf...Is
NOT logique
Not
AND logique
E, AndAlso
OR logique
Oppure, OrElse
XOR logique
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:

CBool,CByte,CChar,CDate,CDbl,CDec,CInt,CLng,CObj,CShort,CSng,CStr

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
CBool
Booleano
Qualsiasi stringa o espressione numerica valida.
CByte
Byte
Da 0 a 255; le frazioni vengono arrotondate.
CChar
Carattere
Qualsiasi espressione String valida; il valore può essere compreso tra 0 e 65 535.
CDate
Data
Qualsiasi rappresentazione valida della data e dell'ora.
CDbl
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.
CDec
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.
CInt
Intero
da -2 147 483 648 a 2 147 483 647; le frazioni vengono arrotondate.
CLng
Numero lungo
da -9 223 372 036 854 775 808 a 9 223 372 036 854 775 807; le frazioni vengono arrotondate.

CObj 
Oggetto
Qualsiasi espressione valida.
CShort
Short
Da -32 768 a 32 767; le frazioni vengono arrotondate.
CSng
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.
CStr
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.

    Environment.Exit(0)

interromperà l'esecuzione del programma con un valore di stato pari a 0.

2.4.2. Struttura di selezione semplice

if condition then
    actions_alors
else
    actions_sinon
end if
  • 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:

10 est > 4

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:
Boolean, Byte, Char, Date, Decimal, Double, Integer, Long, Object, Short, Single et String
  • 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:

i est < 15

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:

somme( 0 2 4 6 8 10)=30

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:

paul
hélène
jacques
sylvie

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
somme=55
somme=55
somme=55
somme=55

2.4.4.3. Istruzioni per la gestione dei cicli

exit do
esce da un ciclo do ... loop
exit for
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:
        Console.Out.WriteLine(unechaine)

In realtà avremmo dovuto scrivere:

        System.Console.Out.WriteLine(unechaine)

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:

dos>boucles1
somme=55
somme=55
somme=55
somme=55

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

    24740        0.15        2072.5

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:

    0                0.65        49062

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:

dos>arg1 a b c
Il y a 3 arguments
argument n° 0=a
argument n° 1=b
argument n° 2=c

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:

dos>enum2
mention=0
Peut mieux faire
Passable
AssezBien
Bien
TrèsBien
Excellent
0
1
2
3
4

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 : 23
Vous vous appelez dupont et vous avez 23 ans
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:

Paramètre formel a=30
Paramètre effectif age=20

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:

Paramètre formel a=30
Paramètre effectif age=30

Il parametro effettivo ha seguito la modifica del parametro formale. Questa modalità di passaggio è adatta ai parametri di output di una funzione.