A18. Procedure e funzioni
Sintassi
Non sempre le procedure e le funzioni fornite dal Vb.Net bastano a soddisfare le nostre necessità di programmazione, quindi si possono
scrivere nuove procedure e nuove funzioni "su misura" per le operazioni che abbiamo intenzione di svolgere. Ogni procedura o funzione è
composta da un nome, un elenco di parametri e dal corpo della stessa, in cui vengono scritte tutte le operazioni da eseguire. Come si è
visto qualche lezione fa, la differenza tra procedure e funzioni è che le prime eseguono semplicemente operazioni, mentre le seconde restituiscono
anche un valore. La sintassi di una procedura è:
mentre quello di una funzione :Sub [nome]([modo] [parametro1]As [tipo], [eccetera])'corpo della procedura End Sub
Bene. Ora è meglio addentrasri un pò di più nello spefico.Function [nome]([modo] [parametro1]As [tipo],[eccetera])As [tipo]'corpo delle funzione Return [valore restituito]End Function
Procedure senza parametri
L'esempio più semplice di una procedura è una proceura senza parametri, che esegue solo istruzioni.
Questo codice provocherà la comparsa sullo schermo del seguente output:Module Module1Dim AAs Integer = 1Sub Moltiplica() A *= 2End Sub Sub Main() Console.WriteLine("A ora vale: " & A) Moltiplica() Console.WriteLine("A ora vale: " & A) Moltiplica() Console.WriteLine("A ora vale: " & A) Console.ReadKey()End Sub End Module
A ora vale: 1 A ora vale: 2 A ora vale: 4Ogni volta che viene chiamata la procedura Moltiplica(), A viene raddoppiata. È essenziale specificare sempre le parentesi dopo una procedura o funzione anche se questa è senza parametri (il compilatore di solito completa automaticamente). Un esempio più complesso:
E avremo come output:Module Module1Dim AAs Integer = 1Sub Moltiplica()Dim BAs Int16For B = 0To A * 5Step A A = A + BNext End Sub Sub Main() Console.WriteLine("A ora vale: " & A) Moltiplica() Console.WriteLine("A ora vale: " & A) Moltiplica() Console.WriteLine("A ora vale: " & A) Console.ReadKey()End Sub End Module
A ora vale: 1 A ora vale: 16 A ora vale: 256La variabile B è dichiarata, come si vede, all'interno della procedura: ciò significa che esiste solamente nel corpo della procedura stessa e non è in alcun modo accessibile al di fuori di essa. Prova ne è il fatto che una volta eseguito il corpo del metodo, la variabile viene cancellata e liberata la parte di memoria che occupa. Variabili di questo tipo vengono definite locali o temporanee. Un'ecceziona a tale regola è costituita dalle variabili static.
Variabili static
Questo tipo di variabili si dichiara sostituendo la keyword "Static" alla consueta "Dim" e l'effetto che si ottiene è una variabile, appunto,
statica:
Il vantaggio di queste variabili è che non vengono mai distrutte, eccetto che quando il programma termina, ovviamente. Possiamo dimostrare questo fatto con un semplice esperimento:Static BAs Byte
Richiamando cinque volte la stessa procedura si otterranno questi risultati:Sub Esperimento()Static BAs Byte B += 1 Console.WriteLine(B)End Sub
1 2 3 4 5Se si dichiarasse B senza usare Static, l'output sarebbe sempre lo stesso: 1. B risiede nella memoria anche dopo che si è usciti dalla procedura e, nel momento in cui il programma vi rientra, essa ha lo stesso valore che aveva prima dell'uscita. Ecco perchè se si incrementa B di uno si ottiene ogni volta un numero diverso.
Inizializzare una variabile static in linea ne imposta solamente il valore iniziale:
I varrà 60 solo quando la procedura o funzione nella quale è dichiarata viene chiamata la prima volta.Static IAs Int32 = 60
Passaggio di parametri: Procedure con parametri
Veniamo ora a vedere come si passano i parametri ad una procedura. Prima di tutto bisogna specificare che i parametri di una procedura/funzione
sono tutti quei valori che gli si passano fra parentesi, separati da virgole, e servono alla stessa per eseguire le proprie operazioni. Essi
sono indicati con un nome arbitrario che serve solo per avere un riferimento all'interno della procedura/funzione ad un certo parametro.
Ci sono due modi di passare i parametri: per valore (ed in questo caso faremo precedere il nome della variabile da ByVal) o per indirizzo
(in cui utilizzeremo ByRef): il primo modo passa al metodo una copia del valore della variabile, cosicchè la variabile non venga
in nessun modo modificata e preservi il proprio contenuto, mentre il passaggio tramite indirizzo passa alla procedura/funzione l'indirizzo di
memoria ove la variabile risiede, e perciò tutte le operazioni eseguite su quella variabile ne modificheranno il valore in modo permanente.
Un esempio:
La variabile globale A (posta al di fuori della procedura Main) viene moltiplicata per il numero specificato come parametro di Moltiplica. Un esempio di passaggio per indirizzo:Module Module1Dim AAs Integer = 1Sub Moltiplica(ByVal PerAs Int16) A *= PerEnd Sub Sub Main() Console.WriteLine("A ora vale: " & A) Moltiplica(6) Console.WriteLine("A ora vale: " & A) Moltiplica(-8) Console.WriteLine("A ora vale: " & A) Console.ReadKey()End Sub End Module
Il programma somma alla variabile passata per indirizzo il doppio di quella passata per valore. Come parametro N della procedura viene passata A, mentre come P prima 6 e poi 8: potrete vedere che il valore di A cambia; infatti l'output sarà:Module Module1Dim AAs Integer = 1Sub Moltiplica(ByRef NAs Int16,ByVal PAs Int16) N += 2 * PEnd Sub Sub Main() Console.WriteLine("A ora vale: " & A) Moltiplica(A, 6) Console.WriteLine("A ora vale: " & A) Moltiplica(A, -8) Console.WriteLine("A ora vale: " & A) Console.ReadKey()End Sub End Module
A ora vale: 1 A ora vale: 13 A ora vale: -3Provate invece in questo modo:
L'output sarà sempre: A ora vale: 1, poichè A viene passata per valore e quindi il suo contenuto non viene modificato.Module Module1Dim AAs Integer = 1Sub Moltiplica(ByVal NAs Int16,ByVal PAs Int16) N += 2 * PEnd Sub Sub Main() Console.WriteLine("A ora vale: " & A) Moltiplica(A, 6) Console.WriteLine("A ora vale: " & A) Moltiplica(A, -8) Console.WriteLine("A ora vale: " & A) Console.ReadKey()End Sub End Module
Funzioni
Un esempio di funzione:
Con la funzione potenza, viene calcolata la potenza di base 'basè ed esponente 'esponentè. Da specificare è che: 1-il tipo della funzione va sempre determinato, in caso contrario la funzione verrà considerata di tipo Object, il che è sconsigliabile, poichè si verifericheranno entrambe le operazioni di boxing e unboxing, come descritto nel capitolo "Tipi reference e tipi value"; 2-La parola chiave Return restituisce il valore specificato dopo ed inoltre termina automaticamente la funzione.Module Module1Function Potenza(ByVal BaseAs Single ,ByVal EsponenteAs Byte ) _As Double Dim XAs Double = 1If Esponente = 0Then Return 1Else If Esponente = 1Then Return BaseElse For iAs Byte = 1To Esponente X *= BaseNext Return XEnd If End If End Function Sub Main()Dim FAs Double Dim bAs Single Dim eAs Byte Console.WriteLine("Inserire base ed esponente:") b = Console.ReadLine e = Console.ReadLine F = Potenza(b, e) Console.WriteLine(b & " elevato a " & e & " è " & F) Console.ReadKey()End Sub End Module
Variable Enregistration
Questa è una tecnica di velocizzazione abbastanza avanzata. Il concetto però è semplice: quando si deve lavorare con un membro di classe che
viene richiamato spesso nel corpo di un metodo, si crea invece una variabile locale per contenere il suo valore. Viene fatto ciò poichè il membro
esiste assieme alla classe e perciò risiede in una parte dello stack o dell'heap managed deputata al suo immagazzinamento a relativamente lungo
termine: la variabile locale, invece, dovrà sicuramente essere distrutta alla fine del metodo, e quindi le viene assegnato uno spazio di memoria
nei registri più veloci dell cpu, quelli con accesso più immediato. Questo permette di aumentare la velocità di esecuzione in modo ragguardevole.
The Totem's Lair - Copyright (C) 2009
È vietata la riproduzione sia totale che parziale del sito.



