Casino online











Mercato forex






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 è:
Sub [nome]([modo] [parametro1] As [tipo], [eccetera])
  'corpo della procedura
End Sub 
mentre quello di una funzione :
Function [nome]([modo] [parametro1] As [tipo],[eccetera]) As [tipo]
  'corpo delle funzione
  Return [valore restituito]
End Function 
Bene. Ora è meglio addentrasri un pò di più nello spefico.

Procedure senza parametri
L'esempio più semplice di una procedura è una proceura senza parametri, che esegue solo istruzioni.
Module Module1
    Dim A As Integer = 1
    Sub Moltiplica()
        A *= 2
    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 
Questo codice provocherà la comparsa sullo schermo del seguente output:
A ora vale: 1
A ora vale: 2
A ora vale: 4 
Ogni 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:
Module Module1
    Dim A As Integer = 1
    Sub Moltiplica()
        Dim B As Int16
        For B = 0 To A * 5 Step A
            A = A + B
        Next
    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 
E avremo come output:
A ora vale: 1
A ora vale: 16
A ora vale: 256 
La 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:
Static B As Byte 
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:
Sub Esperimento()
  Static B As Byte
  B += 1
  Console.WriteLine(B)
End Sub 
Richiamando cinque volte la stessa procedura si otterranno questi risultati:
1
2
3
4
5 
Se 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:
Static I As Int32 = 60 
I varrà 60 solo quando la procedura o funzione nella quale è dichiarata viene chiamata la prima volta.


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:
Module Module1
    Dim A As Integer = 1
    Sub Moltiplica(ByVal Per As Int16)
        A *= Per
    End 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 
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 Module1
    Dim A As Integer = 1
    Sub Moltiplica(ByRef N As Int16, ByVal P As Int16)
        N += 2 * P
    End 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 
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à:
A ora vale: 1
A ora vale: 13
A ora vale: -3 
Provate invece in questo modo:
Module Module1
    Dim A As Integer = 1
    Sub Moltiplica(ByVal N As Int16, ByVal P As Int16)
        N += 2 * P
    End 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 
L'output sarà sempre: A ora vale: 1, poichè A viene passata per valore e quindi il suo contenuto non viene modificato.

Funzioni
Un esempio di funzione:
Module Module1
    Function Potenza(ByVal Base As Single, ByVal Esponente As Byte) _ 
        As Double
        Dim X As Double = 1

        If Esponente = 0 Then
            Return 1
        Else
            If Esponente = 1 Then
                Return Base
            Else
                For i As Byte = 1 To Esponente
                    X *= Base
                Next
                Return X
            End If
        End If
    End Function
    
    Sub Main()
        Dim F As Double
        Dim b As Single
        Dim e As 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 
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.


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.