Sia le funzioni che le sub hanno uno scopo comune in VB.NET e per questo sono molto simili, suddividere il codice in modo da non dover ripetere le stesse routine decine di volte. Mettiamo di voler calcolare il fattoriale di un numero, essendo questa istruzione costante, invece di implementarla ogni volta che serve, possiamo creare una funzione o sub che chiameremo “fattoriale” e la potremmo così utilizzare ogni volta che vogliamo, semplicemente richiamandone il nome. Iniziamo con un pò di teoria spiegando come è strutturata una funzione in VB.NET, vediamone un esempio:
Public Function Fattoriale(ByVal iNumero As Integer) As Long ... End Function
come potete osservare questo è lo scheletro della funzione “Fattoriale” che poi implementeremo. Notiamo l’istruzione Public per indicare che questa funzione è visibile a tutti i moduli, all’interno delle parentesi tonde vanno gli argomenti e dopo questi il valore di ritorno della stessa. In questo esempio abbiamo bisogno di un numero iniziale al quale apporteremo le modifiche necessarie e rimanderemo al chiamante della funzione un valore Long che è il fattoriale dell’argomento stesso. Perchè riceviamo un intero e rimandiamo un long? Semplicemente perché il fattoriale è un’operazione che porta ad avere valori altissimi e quindi un range più ampio è migliore rispetto ad un semplice intero, questo per evitare possibili overflow, mentre l’argomento è intero perché difficilmente avremo dei numeri grandi da calcolare, così facendo risparmiamo memoria allocata. Se notate bene lo scheletro della funzione, potrete vedere l’istruzione ByVal, questa serve a dire che come argomento vogliamo il valore della variabile, mentre con ByRef si richiede l’indirizzo di memoria della stessa, più tardi vedremo le differenze. Ora sviluppiamo la funzione:
Module Corso Public Function Fattoriale(ByVal iNumero As Integer) As Long Dim lFattoriale As Long = 1, i As Integer If iNumero < 0 Or iNumero > 8 Then Fattoriale = -1 End If For i = 1 To iNumero lFattoriale = lFattoriale * i Next Fattoriale = lFattoriale End Function Sub Main() Dim iVal As Integer = 5 Console.WriteLine("Il fattoriale di {0} è {1}", iVal, Fattoriale(iVal)) Console.ReadKey() End Sub End Module
Come potete notare se il numero dato alla funzione è maggiore di 8 questa restituisce un valore negativo per indicare che c’è stato un errore, questo per non andare in overflow. Il valore restituito si invia semplicemente impostando il nome della funzione come una semplice variabile.
Le sub hanno la stessa struttura delle funzioni e la più importante l’abbiamo sempre utilizzata, la Sub Main, che è la principale di un programma e che di solito è l’ingresso dello stesso, ma differiscono dalle function perché non hanno un valore di ritorno. Per quanto riguarda il nostro esempio, il calcolo del fattoriale, possiamo però utilizzare una sub con un argomento di tipo ByRef in modo tale da ritornare il valore, semplicemente cambiandolo nell’indirizzo in memoria della variabile. Ma vediamo praticamente come operare:
Module Corso Public Sub Fattoriale(ByRef lNumero As Long) Dim lFattoriale As Long = 1, i As Integer If lNumero < 0 Or lNumero > 8 Then lNumero = -1 End If For i = 1 To lNumero lFattoriale = lFattoriale * i Next lNumero = lFattoriale End Sub Sub Main() Dim lVal As Long = 5 Fattoriale(lVal) Console.WriteLine("Il fattoriale di 5 è {0}", lVal) Console.ReadKey() End Sub End Module
Come potete notare abbiamo dovuto modificare alcuni punti del programma per avere nella variabile data come argomento il valore calcolato; provate ad esempio a modificare il ByRef con ByVal, vi accorgerete che il valore è sempre quello che abbiamo inserito all’inizio della routine, perché in pratica la variabile non è stata modificata. Vi rendete conto quindi che dare come argomento di una funzione o di una sub un valore per riferimento è molto delicato, perché modifichiamo il valore della cella di memoria occupata dalla variabile del programma principale. Nel proseguio del corso incontreremo tantissime volte le funzioni e le sub, quindi alla fine le imparerete per forza. Alla prossima lezione.