Procedure CAPITOLO 6. 6.1 Introduzione. 6.2 Moduli, classi e procedure



Documenti analoghi
Funzioni in C. Violetta Lonati

FORMULE: Operatori matematici

Struttura logica di un programma

12 - Introduzione alla Programmazione Orientata agli Oggetti (Object Oriented Programming OOP)

CREAZIONE DI UN DATABASE E DI TABELLE IN ACCESS

GUIDA RAPIDA PER LA COMPILAZIONE DELLA SCHEDA CCNL GUIDA RAPIDA PER LA COMPILAZIONE DELLA SCHEDA CCNL

Il database management system Access

Concetto di Funzione e Procedura METODI in Java

EXCEL PER WINDOWS95. sfruttare le potenzialità di calcolo dei personal computer. Essi si basano su un area di lavoro, detta foglio di lavoro,

5.3 TABELLE RECORD Inserire, eliminare record in una tabella Aggiungere record Eliminare record

Istruzioni di installazione di IBM SPSS Modeler Text Analytics (licenza per sito)

Esame di Informatica CHE COS È UN FOGLIO ELETTRONICO CHE COS È UN FOGLIO ELETTRONICO CHE COS È UN FOGLIO ELETTRONICO. Facoltà di Scienze Motorie

Cosa è un foglio elettronico

Excel. A cura di Luigi Labonia. luigi.lab@libero.it

Introduzione allo Scilab Parte 1: numeri, variabili ed operatori elementari

Il calendario di Windows Vista

Matematica in laboratorio

Gestione Rapporti (Calcolo Aree)

Consiglio regionale della Toscana. Regole per il corretto funzionamento della posta elettronica

Introduzione alla programmazione in C

lo PERSONALIZZARE LA FINESTRA DI WORD 2000

Uso di base delle funzioni in Microsoft Excel

Introduzione al Foglio Elettronico

Gestione ed analisi di base dati nell epidemiologia. delle malattie infettive

Corso di Informatica

Manuale Utente Albo Pretorio GA

Metodologie di programmazione in Fortran 90

LABORATORIO DI PROGRAMMAZIONE EDIZIONE 1, TURNO B

Variabili e tipi di dato

Visual Basic.NET La Gestione degli Errori di Federico BARBATI

Convertitori numerici in Excel

Novità di Access 2010

Tricks & Tips. [Access] Tutorial - ActiveX - Controllo Tree View. - Michele de Nittis - Versione: 1 Data Versione: venerdì 30 agosto 2002

Che cos'è un modulo? pulsanti di opzione caselle di controllo caselle di riepilogo

Istruzioni di installazione di IBM SPSS Modeler Text Analytics (utente singolo)

4 3 4 = 4 x x x 10 0 aaa

Inizializzazione, Assegnamento e Distruzione di Classi

I file di dati. Unità didattica D1 1

Corso di Visual Basic (Parte 8)

Le variabili. Olga Scotti

Introduzione alla Programmazione e Applicazioni per la Finanza M2 (Prodotti Derivati) Lezione 9

. A primi passi con microsoft a.ccepss SommarIo: i S 1. aprire e chiudere microsoft access Start (o avvio) l i b tutti i pro- grammi

Mon Ami 3000 Varianti articolo Gestione di varianti articoli

Informatica. Rappresentazione dei numeri Numerazione binaria

Access. Microsoft Access. Aprire Access. Aprire Access. Aprire un database. Creare un nuovo database

Le variabili di Visual Basic consentono di memorizzare temporaneamente valori durante

Matematica - SMID : Programmazione Febbraio 2009 FOGLIO RISPOSTE

per immagini guida avanzata Organizzazione e controllo dei dati Geometra Luigi Amato Guida Avanzata per immagini excel

Università di Torino Facoltà di Scienze MFN Corso di Studi in Informatica. Programmazione I - corso B a.a prof.

A destra è delimitata dalla barra di scorrimento verticale, mentre in basso troviamo una riga complessa.

Workland CRM. Workland CRM Rel /11/2013. Attività --> FIX. Magazzino --> NEW. Nessuna --> FIX. Ordini --> FIX

Esercizi su. Funzioni

Tipi primitivi. Ad esempio, il codice seguente dichiara una variabile di tipo intero, le assegna il valore 5 e stampa a schermo il suo contenuto:

La struttura dati ad albero binario

Arduino: Programmazione

Alcune regole di base per scrivere un programma in linguaggio C

Introduzione al Linguaggio C

Automatizzare i compiti ripetitivi. I file batch. File batch (1) File batch (2) Visualizzazione (2) Visualizzazione

LINGUAGGI DI PROGRAMMAZIONE

Correttezza. Corso di Laurea Ingegneria Informatica Fondamenti di Informatica 1. Dispensa 10. A. Miola Novembre 2007

4. Un ambiente di sviluppo per Java

Capitolo 3. L applicazione Java Diagrammi ER. 3.1 La finestra iniziale, il menu e la barra pulsanti

Analisi sensitività. Strumenti per il supporto alle decisioni nel processo di Valutazione d azienda

Database. Si ringrazia Marco Bertini per le slides

BDX 3D-EDITOR (autore: Marco Bedulli) Scopo del software. Caratteristiche fondamentali. Linguaggi utilizzati. Navigazione 3D

MODULO 4: FOGLIO ELETTRONICO (EXCEL)

Raggruppamenti Conti Movimenti

E possibile modificare la lingua dei testi dell interfaccia utente, se in inglese o in italiano, dal menu [Tools

STRUMENTI. Impostare una presentazione I programmi di presentazione

Uso di JUnit. Fondamenti di informatica Oggetti e Java. JUnit. Luca Cabibbo. ottobre 2012

I database relazionali (Access)

5.6.1 REPORT, ESPORTAZIONE DI DATI

Prof. Giuseppe Chiumeo. Avete già studiato che qualsiasi algoritmo appropriato può essere scritto utilizzando soltanto tre strutture di base:

Manuale di KSystemLog. Nicolas Ternisien

Definire all'interno del codice un vettore di interi di dimensione DIM, es. int array[] = {1, 5, 2, 4, 8, 1, 1, 9, 11, 4, 12};

Modulo. Programmiamo in Pascal. Unità didattiche COSA IMPAREREMO...

PowerPoint 2007 Le funzioni

3 - Variabili. Programmazione e analisi di dati Modulo A: Programmazione in Java. Paolo Milazzo

Applicazioni grafiche

Formattazione e Stampa

RISOLUTORE AUTOMATICO PER SUDOKU

IL LINGUAGGIO Visual Basic

FUNZIONI DI IMPAGINAZIONE DI WORD

STAMPA UNIONE DI WORD

Codifica: dal diagramma a blocchi al linguaggio C++

Dall Algoritmo al Programma. Prof. Francesco Accarino IIS Altiero Spinelli Sesto San Giovanni

Cos è ACCESS? E un programma di gestione di database (DBMS) Access offre: un ambiente user frendly da usare (ambiente grafico)

Volume GESTFLORA. Gestione aziende agricole e floricole. Guidaall uso del software

Corso di Laurea Ingegneria Informatica Fondamenti di Informatica

Concetti Fondamentali

Alla scoperta della nuova interfaccia di Office 2010

Leggere un messaggio. Copyright 2009 Apogeo

Scuola Digitale. Manuale utente. Copyright 2014, Axios Italia

Manuale Amministratore Legalmail Enterprise. Manuale ad uso degli Amministratori del Servizio Legalmail Enterprise

MANUALE EDICOLA 04.05

OSSIF WEB. Manuale query builder

Programmazione in Java (I modulo) Lezione 3: Prime nozioni

Obiettivi del corso. Creare, modificare e formattare un semplice database costituito da tabelle, query, maschere e report utilizzando Access 2000.

DAL DIAGRAMMA AL CODICE

Transcript:

CAPITOLO 6 Procedure Obiettivi Costruire i programmi in modo modulare partendo da piccoli pezzi chiamati procedure Introdurre i metodi Math disponibili in Framework Class Library Creare nuove procedure Capire i meccanismi utilizzati per scambiare le informazioni fra le procedure Descrivere le tecniche di simulazione che utilizzano la generazione di numeri casuali Comprendere come la visibilità degli identificatori sia limitata a specifiche parti di un programma Scrivere e utilizzare le procedure ricorsive 6.1 Introduzione La maggior parte dei programmi per computer scritti per risolvere problemi reali hanno dimensioni decisamente superiori rispetto ai programmi presentati nei primi capitoli di questo libro. L esperienza ha dimostrato che il modo migliore per sviluppare e mantenere un programma di grandi dimensioni è quello di costruirlo partendo da pezzi più piccoli e più facili da gestire rispetto al programma originale. Questo capitolo presenta le caratteristiche del linguaggio Visual Basic che facilitano la progettazione, l implementazione, il funzionamento e la manutenzione di programmi di grandi dimensioni. 6.2 Moduli, classi e procedure I programmi Visual Basic sono composti da vari pezzi, che includono i moduli e le classi. Il programmatore combina nuovi moduli e classi preconfezionate disponibili in.net Framework Class Library (FCL). I moduli e le classi sono formati da pezzi più piccoli: le procedure. Le procedure, quando sono combinate in una classe, si chiamano metodi. Framework Class Library fornisce una ricca collezione di classi e metodi che permettono di eseguire i più comuni calcoli matematici, manipolare stringhe e caratteri, controllare gli errori, gestire l input/output e svolgere molte altre utili operazioni. Tutto questo semplifica il lavoro del programmatore, perché i metodi offrono molte delle funzionalità che servono al programmatore. Nei precedenti capitoli abbiamo introdotto alcune classi FCL, come Console, che fornisce i metodi per l input e l output dei dati.

146 CAPITOLO 6 Ingegneria del software 6.1 Familiarizzate con le classi e i metodi che si trovano in Framework Class Library (FCL). Ingegneria del software 6.2 Dove possibile, utilizzate sempre le classi e i metodi FCL, anziché scrivere nuove classi e nuovi metodi. Ciò consente di ridurre il tempo di sviluppo del programma e impedisce di commettere nuovi errori. Obiettivo efficienza 6.1 I metodi FCL sono stati scritti per essere eseguiti con efficienza. Sebbene FCL disponga di molti metodi che svolgono i compiti più comuni, tuttavia non può disporre di tutte le funzionalità che potrebbero essere richieste dai programmatori. Per questo motivo, Visual Basic consente a un programmatore di definire le sue procedure per soddisfare specifiche esigenze di un programma; queste procedure sono chiamate procedure definite dal programmatore. I programmatori scrivono le procedure per definire specifici compiti che un programma può usare molte volte durante la sua esecuzione. Sebbene la stessa procedura definita dal programmatore possa essere eseguita in più punti del programma, le istruzioni che definiscono effettivamente la procedura vengono scritte una volta soltanto. Una procedura viene invocata da una chiamata di procedura. Questa chiamata specifica il nome della procedura e fornisce le informazioni (come argomenti) di cui la procedura chiamata ha bisogno per completare le attività per le quali è stato progettata. Quando la procedura completa il suo compito, restituisce il controllo alla procedura chiamante (caller). In alcuni casi, la procedura restituisce anche un risultato alla procedura chiamante. Una tipica analogia per spiegare tutto questo è quella della struttura gerarchica di un azienda. Un capo ufficio (la procedura chiamante) chiede a un impiegato (la procedura chiamata) di eseguire un determinato compito e poi di restituire i risultati ottenuti, una volta che questo compito sarà completato. Il capo ufficio non ha bisogno di sapere come quell impiegato eseguirà il compito che gli ha assegnato; l impiegato potrebbe chiamare altri impiegati e il capo ufficio non ne sarebbe a conoscenza. Vedremo presto perché, nascondendo i dettagli di un implementazione, sia possibile ottimizzare la progettazione del software. La Figura 6.1 mostra la procedura Boss che comunica con le procedure Worker1, Worker2 e Worker3 in modo gerarchico. Notate come Worker1 si comporti da boss nei confronti di Worker4 e Worker5 in questo particolare esempio. Sono vari i motivi per cui è bene suddividere un programma in varie procedure. Per prima cosa, questo approccio rende più gestibile lo sviluppo del programma. Un altra motivazione è il riutilizzo del software, ovvero la possibilità di utilizzare le procedure esistenti come blocchi di costruzione per creare nuovi programmi. Applicando opportune convenzioni ai nomi e alle definizioni delle procedure, i programmi possono essere creati partendo da procedure standardizzate che svolgono compiti specifici, anziché utilizzare un codice personalizzato. Una terza motivazione è quella di evitare la ripetizione del codice all interno di un programma. Inserendo il codice in una procedura, è possibile eseguirlo in diversi punti del programma con una semplice chiamata della procedura.

PROCEDURE 147 Figura 6.1 Relazione gerarchica fra procedure Buona abitudine 6.1 Applicate i concetti della modularità per migliorare la chiarezza e l organizzazione dei programmi. Questo non soltanto aiuta gli altri a capire i vostri programmi, ma semplifica anche lo sviluppo, il collaudo e il debugging del codice. Ingegneria del software 6.3 Per favorire il riutilizzo del software, ogni procedura dovrebbe limitarsi a eseguire un solo compito ben definito, mentre il nome della procedura dovrebbe esprimere in modo chiaro tale compito. Ingegneria del software 6.4 Se non riuscite a scegliere un nome conciso che esprime l attività svolta da una procedura, probabilmente la procedura sta cercando di svolgere troppi compiti diversi. Di solito è meglio suddividerla in procedure più piccole. 6.3 Procedure Sub I programmi finora presentati contenevano almeno la definizione di una procedura (Main Main) che chiamava i metodi FCL (come Console.WriteLine) per svolgere i compiti del programma. Vediamo adesso come scrivere le procedure personalizzate. Esaminate l applicazione della Figura 6.2 che usa una procedura Sub (che è chiamata dalla procedura Main) per visualizzare alcuni dati sui pagamenti. Il programma contiene due definizioni di procedure. Le righe 6-14 definiscono la procedura Sub Main, che viene eseguita quando viene caricata l applicazione. Le righe 17-21 definiscono la procedura Sub PrintPay, che è eseguita quando viene chiamata da un altra procedura, in questo caso da Main. La procedura Main effettua quattro chiamate (righe 9-12) della procedura Sub PrintPay, che viene eseguita quattro volte. In questo esempio gli argomenti della procedura sono delle costanti, ma possono essere anche variabili o espressioni. Per esempio, l istruzione PrintPay(employeeOneExtraHours, employeeonewage * 1.5) può essere utilizzata per visualizzare le informazioni sui pagamenti di un impiegato il cui lavoro straordinario (employeeoneextrahours employeeoneextrahours) ha un costo pari a una volta e mezza l orario normale (employeeonewage employeeonewage).

148 CAPITOLO 6 1 Figura 6.2: Payment.vb 2 Visualizza le informazioni sui pagamenti 3 4 Module modpayment 5 6 Sub Main() 7 8 chiama la procedura PrintPay 4 volte 9 PrintPay(40, 10.5) 10 PrintPay(38, 21.75) 11 PrintPay(20, 13) 12 PrintPay(50, 14) 13 14 End Sub Main 15 16 visualizza l importo nella finestra di comando 17 Sub PrintPay(ByVal hours As Double, ByVal wage As Decimal) 18 19 pay = hours * wage 20 Console.WriteLine( The payment is {0:C}, hours * wage) 21 End Sub PrintPay 22 23 End Module modpayment The payment is $420.00 The payment is $826.50 The payment is $260.00 The payment is $700.00 Figura 6.2 Procedura Sub per visualizzare i pagamenti Quando Main chiama PrintPay, il programma crea una copia del valore di ogni argomento (40 e 10.5 nella riga 9). Il controllo del programma passa alla prima riga della procedura PrintPay; questa procedura riceve i valori copiati e li memorizza nelle variabili hours e wage. Le variabili che ricevono i valori copiati degli argomenti sono dette parametri. Poi, PrintPay calcola il prodotto hours * wage e visualizza il risultato, utilizzando il formato della valuta, come indica la lettera C (iniziale di currency) nella riga 20. Quando viene eseguita l istruzione End Sub nella riga 21, il controllo ritorna alla procedura Main che ha effettuato la chiamata (caller). La prima riga della procedura PrintPay (riga 17) mostra (fra parentesi) che PrintPay dichiara la variabile hours di tipo Double e la variabile wage di tipo Decimal. Questi parametri memorizzano i valori passati a PrintPay all interno di questa procedura. Notate che l intera definizione della procedura PrintPay appare all interno del corpo del modulo modpayment. Tutte le procedure devono essere definite all interno di un modulo o di una classe. Il formato della definizione di una procedura Sub è il seguente: Sub nome-procedura(lista-parametri) dichiarazioni e istruzioni End Sub

PROCEDURE 149 La prima riga è detta intestazione della procedura. Il nome-procedura, che segue la parola chiave Sub nell intestazione della procedura, può essere qualsiasi identificatore valido ed è utilizzato per chiamare la procedura all interno del programma. La lista-parametri è un elenco di elementi separati da una virgola in cui la procedura Sub dichiara il tipo e il nome di ogni parametro. Ci deve essere almeno un argomento nella chiamata della procedura per ogni parametro dell intestazione (c è un eccezione a questa regola, come vedremo nel Paragrafo 6.17). Gli argomenti devono essere compatibili anche con i tipi di parametri (Visual Basic deve essere in grado di assegnare il valore dell argomento al parametro). Per esempio, un parametro di tipo Double può ricevere i valori 7.35, 22 o.03546, ma non i caratteri ciao, perché Double non può contenere stringhe di caratteri. Il Paragrafo 6.6 descrive dettagliatamente questo tema. Se una procedura non riceve alcun valore, la lista dei parametri è vuota (il nome della procedura è seguito da una coppia di parentesi vuote). Buona abitudine 6.2 Inserite una riga vuota prima e dopo la definizione di una procedura per mettere in evidenza le procedure dal resto del codice e migliorare la leggibilità dei programmi. Errore tipico 6.1 È un errore di sintassi definire una procedura all esterno della definizione di una classe o di un modulo. Notate che le dichiarazioni dei parametri nell intestazione della procedura PrintPay (riga 17) sono simili alle dichiarazioni delle variabili, con la differenza che usano la parola chiave ByVal, anziché Dim. ByVal specifica che il programma chiamante deve passare al parametro una copia del valore dell argomento; tale valore può essere utilizzato nel corpo della procedura Sub. Il Paragrafo 6.9 esamina dettagliatamente il passaggio degli argomenti. Errore tipico 6.2 È un errore di sintassi dichiarare una variabile nel corpo della procedura con lo stesso nome del parametro nell intestazione della procedura. Collaudo e messa a punto 6.1 Anche se è consentito, un argomento passato a una procedura non dovrebbe avere lo stesso nome del corrispondente parametro nella definizione della procedura. Questa distinzione evita ogni ambiguità che potrebbe determinare errori logici. Le dichiarazioni e le istruzioni nella definizione della procedura formano il corpo della procedura. Il corpo della procedura contiene il codice Visual Basic che svolge le azioni, manipolando o interagendo con i parametri. Il corpo della procedura deve terminare con le parole chiave End Sub, che definiscono la fine della procedura. Il corpo di una procedura è detto anche blocco. Un blocco è una sequenza di istruzioni e dichiarazioni raggruppate insieme come il corpo di una struttura; termina con l istruzione End, Next, Else o Loop, a seconda del tipo di struttura. Le variabili possono essere dichiarate in qualsiasi blocco; i blocchi possono essere nidificati. Errore tipico 6.3 È un errore di sintassi definire una procedura all interno di un altra; le procedure non possono essere nidificate.

150 CAPITOLO 6 Il controllo ritorna al caller quando l esecuzione raggiunge l istruzione End Sub (la fine del corpo della procedura). In alternativa, è possibile utilizzare le parole chiave Return ed Exit Sub in qualsiasi punto di una procedura per restituire il controllo al punto in cui è stata chiamata la procedura Sub. Più avanti descriveremo meglio Return ed Exit Sub. Buona abitudine 6.3 La scelta di nomi significativi per le procedure e i parametri rende i programmi più leggibili e riduce la lunghezza dei commenti. Ingegneria del software 6.5 I nomi delle procedure di solito sono verbi, perché una procedura svolge delle operazioni sui dati. Per convenzione, i nomi delle procedure definite dai programmatori iniziano con la prima lettera maiuscola. Per esempio, una procedura che invia un messaggio di posta elettronica potrebbe essere chiamata SendMail. Ingegneria del software 6.6 Una procedura che richiede un numero elevato di parametri, di solito, svolge troppi compiti. È consigliabile suddividere la procedura in procedure più piccole che svolgono compiti più semplici. Come regola generale, l intestazione di una procedura dovrebbe occupare una sola riga. Ingegneria del software 6.7 Come regola generale, una procedura dovrebbe occupare un solo foglio di carta o, meglio ancora, non dovrebbe superare la metà di un foglio. Indipendentemente dalla lunghezza, la procedura deve svolgere bene il suo compito. Collaudo e messa a punto 6.2 La procedure piccole sono più semplici da provare, correggere e capire di quelle più grandi. Obiettivo efficienza 6.2 Quando un programmatore divide una procedura in numerose procedure che comunicano fra di loro, questo processo di comunicazione richiede tempo e, a volte, riduce le prestazioni del programma. Ingegneria del software 6.8 Le intestazioni e le chiamate delle procedure devono concordare con il numero, il tipo e l ordine dei parametri. Il Paragrafo 6.17 tratta le eccezioni a questa regola. 6.4 Procedure Function Le procedure Function sono simili alle procedure Sub, con una differenza importante: le procedure Function restituiscono un valore alla procedura chiamante, le procedure Sub no. L applicazione della Figura 6.3 usa la procedura Function Square per calcolare i quadrati dei numeri interi compresi fra 1 e 10.

PROCEDURE 151 1 Figura 6.3: SquareInteger.vb 2 Procedura Function per calcolare i quadrati 3 4 Module modsquareinteger 5 6 Sub Main() 7 Dim i As Integer contatore 8 9 Console.WriteLine( Number & vbtab & Square & vbcrlf) 10 11 calcola i quadrato di numeri interi da 1 a 10 12 For i = 1 To 10 13 Console.WriteLine(i & vbtab & Square(i)) 14 Next 15 16 End Sub Main 17 18 Esegue Function Square 19 soltanto se la funzione è esplicitamente chiamata 20 Function Square(ByVal y As Integer) As Integer 21 Return y ^ 2 22 End Function Square 23 24 End Module modsquareinteger Number Square 1 1 2 4 3 9 4 16 5 25 6 36 7 49 8 64 9 81 10 100 Figura 6.3 La procedura Function Square calcola il quadrato di numeri interi La struttura For (righe 12-14) visualizza i risultati dei quadrati dei primi 10 numeri interi. Ogni iterazione del ciclo calcola il quadrato della variabile di controllo i e visualizza il risultato nella finestra di comando. La procedura Function Square viene chiamata (riga 13) con l espressione Square(i). Quando il controllo del programma raggiunge questa espressione, viene chiamata la funzione Function Square (righe 20-22). A questo punto, il programma crea una copia del valore di i (l argomento) e il controllo passa alla prima riga di Function Square. La procedura Square riceve la copia del valore di i, che registra nel parametro y. La riga 21 è un istruzione Return, che termina l esecuzione della procedura e fornisce il risultato di y ^ 2 al caller. Il risultato viene restituito al punto della riga 13 dove è stata chiamata la procedura Square. La riga 13 visualizza il valore di i e il valore fornito da Square nella finestra di comando. Questo processo si ripete 10 volte.

152 CAPITOLO 6 Il formato della definizione di una procedura Function è il seguente: Function nome-procedura(lista-parametri) ) As tipo-risultato dichiarazioni e istruzioni End Function I termini nome-procedura, lista-parametri, dichiarazioni e istruzioni hanno lo stesso significato dei corrispondenti termini nella definizione di una procedura Sub. Nell intestazione della procedura Function, il termine tipo-risultato indica il tipo di dati del risultato che la procedura fornirà al programma che l ha chiamata. L istruzione Return espressione può essere inserita nel corpo di una procedura Function e restituisce il valore dell espressione al caller. Se necessario, Visual Basic tenta di convertire l espressione nel tipo-risultato della procedura Function. Le procedure Function restituiscono un solo valore. Quando viene eseguita l istruzione Return, il controllo ritorna immediatamente al punto in cui la procedura è stata chiamata. Errore tipico 6.4 Se l espressione di un istruzione Return non può essere convertita nel tipo-risultato della procedura Function, si verifica un errore durante l esecuzione (errore di runtime). Errore tipico 6.5 Se una procedura Function non fornisce un risultato (manca l istruzione Return), la procedura restituisce il valore di default, che spesso genera un errore di output. 6.5 Metodi Un metodo è una procedura qualsiasi che è contenuta all interno di una classe. Abbiamo già presentato vari metodi FCL (ovvero i metodi contenuti in classi che appartengono a FCL). I programmatori possono definire i loro metodi all interno di classi personalizzate, per esempio una classe utilizzata per definire un applicazione Windows. La Figura 6.4 riporta un applicazione Windows che usa due metodi per calcolare il maggiore di tre valori Double. Molte delle applicazioni finora presentate hanno facilitato l interazione con l utente utilizzando la finestra di comando (dove l utente può digitare un valore di input per il programma) o una finestra di dialogo (che presenta un messaggio all utente e gli consente di fare clic sul pulsante OK per confermare i dati della finestra). Nel Capitolo 4 abbiamo introdotto le applicazioni Windows creando un programma che visualizzava le informazioni in una label di un form. Sebbene la finestra di comando e le finestre di dialogo siano strumenti validi per ricevere l input dall utente e visualizzare l output, tuttavia le loro capacità sono limitate: la finestra di comando può ricevere una sola riga di input alla volta dall utente e la finestra di dialogo può visualizzare soltanto un messaggio. È normale ricevere più input alla volta (come i tre valori di questo esempio) o visualizzare contemporaneamente più blocchi di dati. Per introdurre un interfaccia di programmazione più sofisticata, il programma della Figura 6.4 usa la gestione degli eventi dell interfaccia GUI (ovvero la capacità di reagire a una variazione dello stato dell interfaccia GUI, come quando l utente fa clic su un pulsante).

PROCEDURE 153 La classe FrmMaximum usa un interfaccia GUI che è formata da tre TextBoxes (txtfirst txtfirst, txtsecond e txtthird) per l input dell utente, un pulsante (cmdmaximum cmdmaximum) per svolgere i calcoli e quattro Label, fra cui lblmaximum, per visualizzare i risultati. Abbiamo creato questi componenti visivamente, mediante Toolbox, e abbiamo cambiato le loro proprietà nella finestra Properties. Le righe 7-21 sono dichiarazioni che indicano il nome di ogni componente. Sebbene queste righe di codice facciano parte del codice generato da Visual Studio.NET, le abbiamo riportate per indicare gli oggetti che fanno parte del form (come sempre, il codice completo di questo programma può essere scaricato dal sito Web indicato nella Prefazione del libro). 1 Figura 6.4: Maximum.vb 2 Trova il massimo di tre numeri di input 3 4 Public Class FrmMaximum 5 Inherits System.Windows.Forms.Form 6 7 richiede i tre valori di input 8 Friend WithEvents lblone As System.Windows.Forms.Label 9 Friend WithEvents lbltwo As System.Windows.Forms.Label 10 Friend WithEvents lblthree As System.Windows.Forms.Label 11 12 visualizza il risultato 13 Friend WithEvents lblmaximum As System.Windows.Forms.Label 14 15 legge tre numeri 16 Friend WithEvents txtfirst As System.Windows.Forms.TextBox 17 Friend WithEvents txtsecond As System.Windows.Forms.TextBox 18 Friend WithEvents txtthird As System.Windows.Forms.TextBox 19 20 legge gli input e calcola il risultato 21 Friend WithEvents cmdmaximum As System.Windows.Forms.Button 22 23 codice generato da Visual Studio.NET 24 25 acquisisce i valori dai box di testo, avvia Maximum 26 Private Sub cmdmaximum_click(byval sender As System.Object, _ 27 ByVal e As System.EventArgs) Handles cmdmaximum.click 28 29 Dim value1, value2, value3 As Double 30 31 value1 = txtfirst.text 32 value2 = txtsecond.text 33 value3 = txtthird.text 34 35 lblmaximum.text = Maximum(value1, value2, value3) 36 End Sub cmdmaximum_click 37 Figura 6.4 Il metodo che determina il massimo di tre numeri (continua)

154 CAPITOLO 6 38 trova il massimo di tre valori 39 Function Maximum(ByVal valueone As Double, _ 40 ByVal valuetwo As Double, ByVal valuethree As Double) 41 42 Return Math.Max(Math.Max(valueOne, valuetwo), valuethree) 43 End Function Maximum 44 45 End Class FrmMaximum Figura 6.4 Il metodo che determina il massimo di tre numeri La riga 5 indica che la classe FrmMaximum eredita (Inherits Inherits) le proprietà dalla classe System.Windows.Forms.Form. Ricordiamo che tutti i form derivano da System.Windows. Forms.Form. Una classe può ereditare gli attributi e i comportamenti (dati e metodi) da un altra classe, se il nome della classe viene specificato a destra della parola chiave Inherits. Il Capitolo 9 tratta dettagliatamente l ereditarietà. FrmMaximum contiene due metodi definiti dal programmatore. Il metodo Maximum (righe 39-43) riceve tre parametri Double e fornisce il valore massimo di questi parametri. Notate che la definizione di questo metodo somiglia alla definizione di una procedura Function in un modulo. Il programma include anche il metodo cmdmaximum_click (righe 26-36). Quando l utente fa doppio clic su un componente, come Button, in modalità progetto, l IDE genera un metodo che gestisce un evento (gestore di eventi). Un evento rappresenta un azione dell utente, per esempio fare clic su un pulsante (Button Button) o modificare un valore. Un gestore di eventi è un metodo che viene eseguito quando si verifica un determinato evento. In questo caso, il metodo cmdmaximum_click gestisce l evento in cui l utente fa clic sul pulsante cmdmaximum. I programmatori scrivono il codice per svolgere determinati compiti quando si verificano tali eventi. Impiegando gli eventi e gli oggetti, i programmatori possono creare applicazioni che consentono di interagire in modo più sofisticato con l utente rispetto a quanto finora visto. I nomi dei gestori degli eventi creati dall IDE iniziano con il nome dell oggetto, seguito dal simbolo di sottolineatura e dal nome dell evento. Nel Capitolo 12 spiegheremo le tecniche che consentono a un programmatore di creare i propri gestori di eventi. Quando l utente fa clic sul pulsante cmdmaximum, viene eseguita la procedura cmdmaximum_click (righe 26-36). Le righe 31-33 leggono i valori contenuti nei tre box di testo utilizzando la proprietà Text. I valori vengono convertiti implicitamente nel tipo Double e memorizzati nelle variabili value1, value2 e value3.

PROCEDURE 155 La riga 35 chiama il metodo Maximum (righe 39-43) con gli argomenti value1, value2 e value3. I valori di questi argomenti vengono poi memorizzati nei parametri valueone, valuetwo e valuethree nel metodo Maximum. Questo metodo fornisce il risultato dell espressione nella riga 42, che effettua due chiamate del metodo Max della classe Math. Il metodo Max calcola il massimo dei suoi due argomenti Double; la riga 42 prima confronta valueone e valuetwo e poi il valore fornito a valuethree dalla prima chiamata del metodo. Le chiamate dei metodi, come Math.Max, che sono definite in una classe di FCL devono includere il nome della classe e l operatore punto (.), detto anche operatore di accesso ai membri. Le chiamate dei metodi definiti nella classe che contiene le chiamate, invece, richiedono soltanto che sia specificato il nome del metodo. Quando il controllo del programma ritorna al metodo cmdmaximum_click, la riga 35 assegna il valore fornito dal metodo Maximum alla proprietà Text di lblmaximum, che così viene visualizzato all utente. Notate che, quando digitate la parentesi aperta dopo il nome di un metodo o di una procedura, Visual Studio visualizza una finestra che contiene i nomi e i tipi degli argomenti della procedura. Questa è la caratteristica Parameter Info dell IDE (Figura 6.5). La finestra Parameter Info semplifica notevolmente il codice, perché identifica le procedure accessibili e i loro argomenti. La finestra Parameter Info visualizza anche le informazioni delle procedure definite dai programmatori e tutti i metodi contenuti in FCL. Buona abitudine 6.4 Per rendere più significative le informazioni fornite dalla finestra Parameter Info, assegnate ai parametri dei nomi che descrivono bene le loro funzioni. Visual Basic dispone anche della caratteristica IntelliSense, che visualizza tutti i membri di una classe. Per esempio, quando il programmatore digita l operatore punto (.) dopo il nome di una classe (Math Math, nella Figura 6.6), IntelliSense fornisce un elenco di tutti i metodi disponibili nella classe. La classe Math contiene numerosi metodi che consentono al programmatore di svolgere molte delle più comuni operazioni matematiche. Il prospetto della Figura 6.7 riporta alcuni metodi FCL della classe Math. Le variabili x e y di questo prospetto sono di tipo Double, tuttavia molti metodi hanno versioni che accettano valori di altro tipo come argomenti. La classe Math definisce anche due costanti matematiche: Math.PI e Math.E. La costante Math.PI (3.14159265358979323846) è il rapporto fra la circonferenza di un cerchio e il suo diametro. La costante Math.E (2.7182818284590452354) è la base dei logaritmi naturali (calcolati con il metodo Math.Log). La finestra Parameter Info Figura 6.5 La finestra Parameter Info dell IDE di Visual Studio.NET

156 CAPITOLO 6 La finestra IntelliSense Figura 6.6 La finestra IntelliSense dell IDE di Visual Studio.NET Errore tipico 6.6 È un errore di sintassi chiamare un metodo della classe Math senza anteporre al metodo il nome della classe Math e l operatore punto (.). Ingegneria del software 6.9 Non è necessario aggiungere un riferimento assembly per utilizzare i metodi della classe Math in un programma, in quanto questa classe si trova nel namespace System, che viene implicitamente aggiunto a tutte le applicazioni della console. 6.6 Promozione degli argomenti Un altra importante caratteristica delle definizioni delle procedure è la coercizione degli argomenti, che consiste nel forzare un argomento a diventare del tipo appropriato per essere passato a una procedura. Visual Basic supporta le conversioni di ampliamento e di riduzione. La conversione di ampliamento si verifica quando un tipo di dati viene trasformato in un altro tipo (che di solito può contenere più dati) senza perdita di dati. La conversione di riduzione si verifica quando c è il rischio di perdere dati durante la trasformazione da un tipo di dati a un tipo che può contenere meno dati. La Figura 6.8 elenca le conversioni di ampliamento supportate da Visual Basic. Per esempio, il metodo Sqrt della classe Math può essere chiamato con un argomento intero, anche se il metodo è definito nella classe Math in modo da ricevere un argomento Double. L istruzione Console.Write(Math.Sqrt(4)) valuta correttamente Math.Sqrt(4) e visualizza il valore 2. Visual Basic promuove (converte) il valore intero 4 nel valore Double 4.0 prima che il valore venga passato a Math.Sqrt. In questo caso, il valore dell argomento non corrisponde esattamente al tipo di parametro nella definizione del metodo, quindi viene effettuata una conversione di ampliamento implicita che trasforma il valore nel tipo appropriato, prima che il metodo venga chiamato. Visual Basic effettua anche conversioni di riduzione degli argomenti che vengono passati alle procedure. Per esempio, se la variabile di stringa number contiene il valore 4, il metodo Math.Sqrt(number) fornisce correttamete il valore 2. Tuttavia, alcune conversioni di ridu-

PROCEDURE 157 Metodo Descrizione Esempio Abs(x) Calcola il valore assoluto di x Abs(23.7) è 23.7 Abs(0) è 0 Abs( 23.7) è 23.7 Ceiling(x) Arrotonda x all intero più piccolo Ceiling(9.2) è 10.0 non minore di x Ceiling( 9.8) è 9.0 Cos(x) Calcola il coseno di x (x in radianti) Cos(0.0) è 1.0 Exp(x) Calcola la potenza e x Exp(1.0) è approssimativamente pari a 2.71828182845905 Exp(2.0) è approssimativamente pari a 7.38905609893065 Floor(x) Arrotonda x all intero più grande Floor(9.2) è 9.0 non maggiore di x Floor( 9.8) è 10.0 Log(x) Calcola il logaritmo naturale Log(2.7182818284590451) è (in base e) di x approssimativamente pari a 1.0 Log(7.3890560989306504) è approssimativamente pari a 2.0 Max(x, y) Fornisce il valore massimo fra x e y Max(2.3, 12.7) è 12.7 (ha le versioni per i valori Single, Max( 2.3, 12.7) è 2.3 Integer e Long) Min(x, y) Fornisce il valore minimo fra x e y Min(2.3, 12.7) è 2.3 (ha le versioni per i valori Single, Min( 2.3, 12.7) è 12.7 Integer e Long) Pow(x, y) Calcola x elevato a y (x y ) Pow(2.0, 7.0) è 128.0 Pow(9.0,.5) è 3.0 Sin(x) Calcola il seno di x (x in radianti) Sin(0.0) è 0.0 Sqrt(x) Calcola la radice quadrata di x Sqrt(9.0) è 3.0 Sqrt(2.0) è 1.4142135623731 Tan(x) Calcola la tangente di x (x in radianti) Tan(0.0) è 0.0 Figura 6.7 Metodi della classe Math zione possono fallire, provocando degli errori logici e di runtime. Per esempio, se number contiene il valore ciao e viene passato al metodo Math.Sqrt, si verifica un errore di runtime. Nel prossimo paragrafo esamineremo alcune precauzioni che può prendere il programmatore per evitare questi problemi. Errore tipico 6.7 Quando si effettua una conversione di riduzione (per esempio, da Double a Integer), la trasformazione di un valore da un tipo di dato primitivo a un altro tipo di dato primitivo potrebbe modificare il valore. Inoltre, la conversione da un valore intero a un valore floating-point e poi di nuovo a un valore intero può introdurre nel risultato degli errori di arrotondamento.

158 CAPITOLO 6 Tipi di dati Boolean Byte Char Date Decimal Double Integer Long Object Short Single String Tipi di conversioni Object Short, Integer, Long, Decimal, Single, Double o Object String o Object Object Single, Double o Object Object Long, Decimal, Single, Double o Object Decimal, Single, Double o Object nessuno Integer, Long, Decimal, Single, Double o Object Double o Object Object Figura 6.8 Conversioni di ampliamento di Visual Basic La promozione degli argomenti si applica non soltanto ai valori dei dati primitivi che vengono passati come argomenti ai metodi, ma anche alle espressioni che contengono i valori di due o più tipi di dati. Queste espressioni sono chiamate espressioni di tipo misto. In un espressione di tipo misto ogni valore viene promosso al tipo più alto dell espressione (in altre parole, la conversione di ampliamento continua finché i valori non saranno dello stesso tipo). Per esempio, se singlenumber è di tipo Single e integernumber è di tipo Integer, quando Visual Basic calcola l espressione singlenumber + integernumber il valore di integernumber viene convertito nel tipo Single e poi sommato a single- Number, generando un risultato di tipo Single. Sebbene i tipi di dati originali dei valori siano mantenuti, viene creata una versione temporanea di ogni valore da utilizzare nell espressione e i tipi di dati delle versioni temporanee vengono modificati in modo appropriato. 6.7 Conversione dei tipi di dati Visual Basic offre varie opzioni per controllare il modo in cui il compilatore dovrà gestire i tipi di dati. Queste opzioni possono aiutare i programmatori a evitare gli errori derivanti dalle conversioni di riduzione degli argomenti, rendendo il codice più leggibile e sicuro. La prima opzione è Option Explicit, che è impostata a On per default (nel senso che è stata abilitata nei programmi Visual Basic creati nei Capitoli 2-5). Option Explicit forza il programmatore a dichiarare esplicitamente tutte le variabili prima che siano utilizzate nel programma. Forzando le dichiarazioni esplicite, si eliminano gli errori ortografici e altri errori subdoli che possono verificarsi se Option Explicit non è attivata. Per esempio, se Option Explicit è impostata a Off, il compilatore interpreta i nomi delle variabili che hanno errori ortografici come nuove dichiarazioni di variabili, generando così degli errori difficili da identificare.

PROCEDURE 159 Un altra opzione, che per default è impostata a Off, è Option Strict. Visual Basic fornisce Option Strict come strumento per migliorare la leggibilità dei programmi e per ridurre il tempo di debugging. Se è impostata a On, Option Strict forza il compilatore a controllare tutte le conversioni degli argomenti e richiede al programmatore di svolgere una conversione esplicita per tutte le conversioni di riduzione che potrebbero causare la perdita dei dati (conversione da Double a Integer) o la conclusione del programma (conversione di una variabile di tipo String, come ciao, a Integer). I metodi della classe Convert cambiano i tipi di dati in modo esplicito. Il nome del metodo di conversione è formato dalla parola chiave To seguita dal nome del tipo di dati in cui il metodo dovrà convertire il suo argomento. Per esempio, per memorizzare la stringa immessa in input dall utente nella variabile number di tipo Integer (rappresentata in Visual Basic.NET come tipo Int32, un numero intero a 32 bit) con Option Strict impostata a On, utilizziamo l istruzione number = Convert.ToInt32(Console.ReadLine()) Quando Option Strict è impostata a Off, Visual Basic svolge implicitamente queste conversioni di tipo, nel senso che il programmatore potrebbe non rendersi conto che sta per essere effettuata una conversione di riduzione. Se i dati che stanno per essere convertiti non sono compatibili con il nuovo tipo di dati, si verifica un errore di runtime. Option Strict richiama l attenzione del programmatore sulle conversioni di riduzione, in modo che possano essere eliminate del tutto o gestite in modo appropriato. Nel Capitolo 11 descriveremo le tecniche per gestire gli errori provocati dal fallimento delle conversioni di riduzione degli argomenti. Ingegneria del software 6.10 Le conversioni esplicite consentono ai programmi di essere eseguiti in modo più efficiente, perché non è necessario determinare il tipo di dati da modificare prima di effettuare la conversione. Da questo punto in poi, tutti gli esempi avranno Option Strict impostata a On. Option Strict può essere attivata attraverso l IDE facendo clic con il pulsante destro del mouse sul nome del progetto in Solution Explorer. Dal menu risultante, selezionate Properties per aprire la finestra di dialogo Property Pages rappresentata nella Figura 6.9. Dall albero delle directory, che si trova a sinistra in questa finestra di dialogo, selezionate Build dall elenco Common Properties. Al centro della finestra di dialogo c è una casella a discesa chiamata Option Strict. Per default, questa opzione è impostata a Off. Selezionate On dalla casella a discesa e fate clic sul pulsante Apply. Se Option Strict è impostata a On nella finestra Property Pages, i suoi effetti si applicano globalmente all intero progetto. Il programmatore può anche abilitare Option Strict all interno di un singolo file di codice, digitando Option Strict On all inizio del codice, prima delle dichiarazioni e delle istruzioni Imports. 6.8 Valori e riferimenti Nel prossimo paragrafo descriveremo le tecniche per passare gli argomenti alle procedure come valori o come riferimenti. Per capire questo, occorre prima fare una distinzione fra i tipi di dati in Visual Basic.

160 CAPITOLO 6 Figura 6.9 La finestra di dialogo Property Pages con Option Strict impostata a On I tipi di dati di Visual Basic possono essere classificati come valori primitivi o come riferimenti a valori primitivi. Una variabile di tipo valore primitivo contiene i dati effettivi. Di solito, il valore primitivo viene utilizzato per un singolo dato, come un valore Integer o Double. Invece, una variabile di tipo riferimento contiene l indirizzo di una locazione della memoria dove sono registrati i dati. La locazione in memoria può contenere più dati. I dati di tipo riferimento sono globalmente detti oggetti e sono descritti nei Capitoli 8, 9 e 10. Entrambi i tipi di dati (valore e riferimento) includono tipi predefiniti e tipi creati dal programmatore. I tipi di valori predefiniti includono i tipi numeri interi (Byte Byte, Short, Integer e Long), i tipi floating-point (Single e Double) e i tipi Boolean, Date, Decimal e Char. I tipi di riferimenti predefiniti includono Object e String (anche se il tipo String spesso si comporta più come un valore, come vedremo nel prossimo paragrafo). I tipi di valori che possono essere costruiti dal programmatore includono le strutture (Structure Structure) e le enumerazioni (Enum Enum). I tipi di riferimenti che possono essere creati dal programmatore includono le classi, le interfacce e le classi delegate. I tipi di dati definiti dal programmatore sono descritti nei Capitoli 8, 9 e 14. La tabella nella Figura 6.10 elenca i tipi di dati primitivi che formano i blocchi di costruzione per tipi di dati più complessi, come le classi. Se Option Explicit è impostata a On, tutte le variabili devono avere un tipo di dati prima di essere utilizzate in un programma. La tabella fornisce per ogni tipo di valore la dimensione in bit (un byte è formato da 8 bit) e l intervallo dei valori consentiti. Per favorire la portabilità, la Microsoft ha scelto di utilizzare gli standard internazionali sia per i formati dei caratteri (Unicode) sia per i numeri floatingpoint (IEEE 754). I valori digitati direttamente nel codice del programma si chiamano literal. Ogni literal corrisponde a uno dei tipi di dati primitivi. Abbiamo già visto i valori literal per i tipi di dati

PROCEDURE 161 Tipo Dimensione (bit) Valori (*) Standard Boolean 16 True o False Char 16 Un carattere Unicode Unicode Byte 8 Da 0 a 255 Date 64 Dal 1 gennaio 0001 al 31 dicembre 9999 Da 0:00:00 a 23:59:59 Decimal 128 Da 1.0E 28 a 7.9E+28 Short 16 Da 32,768 a 32,767 Integer 32 Da 2,147,483,648 a 2,147,483,647 Long 64 Da 9,223,372,036,854,775,808 a 9,223,372,036,854,775,807 Single 32 Da ±1.5E 45 a ±3.4E+38 IEEE 754 Double 64 Da ±5.0E 324 a ±1.7E+308 IEEE 754 Object 32 Dato di qualsiasi tipo String Da 0 a circa 2 miliardi di caratteri Unicode Unicode (*) Nella notazione anglosassone, il punto (.) serve a separare la parte intera dalla parte decimale di un numero, mentre la virgola (,) serve a separare le migliaia della parte intera. Figura 6.10 Tipi di dati primitivi di Visual Basic più comuni, come String, Integer e Double. Tuttavia, alcuni tipi di dati di Visual Basic usano delle notazioni speciali per creare i valori literal. Per esempio, per creare un valore literal di tipo Char, basta aggiungere la lettera c dopo un singolo carattere di tipo String. L istruzione Dim character As Char = Z c dichiara la variabile character di tipo Char e la inizializza con la lettera Z. Analogamente, è possibile creare i valori literal di specifici numeri interi, aggiungendo a un valore il carattere S (per Short), I (per Integer) o L (per Long). Per creare literal floating-point, basta accodare al valore floating-point il carattere F (per Single) o R (per Double). Il carattere D può essere utilizzato per creare literal Decimal. Visual Basic consente anche di creare literal floating-point nella notazione scientifica: digitate il numero floating-point seguito dal character E e da un esponente positivo o negativo di una potenza di 10. Per esempio, 1.909E 5 corrisponde al valore 0.00001909. Questa notazione è utile per specificare valori floating-point che sono troppo grandi o troppo piccoli da scrivere nella notazione fixed-point. La Figura 6.11 elenca i caratteri di tipo adottati da Visual Basic e i corrispondenti esempi di literal per ogni tipo di dato. Tutti i valori literal devono essere compresi negli intervalli dei corrispondenti tipi di dati riportati nella Figura 6.10.

162 CAPITOLO 6 Tipo di dato Carattere di tipo Esempio Char c u c Single F 9.802E+31F Double R 6.04E 187R Decimal D 128309.76D Short S 3420S Integer I 867I Long L 19235827493259374L Figura 6.11 Literal con i caratteri di tipo 6.9 Passare gli argomenti Gli argomenti possono essere passati alle procedure in due modi: come valori o come riferimenti. Quando un argomento viene passato come valore, il programma crea una copia del valore dell argomento e la passa alla procedura chiamata. Quando l argomento viene passato come valore, le modifiche apportate alla copia della procedura chiamata non influiscono sul valore della variabile originale. Se, invece, l argomento viene passato come riferimento, il caller consente alla procedura chiamata di accedere e modificare direttamente i dati originali. La Figura 6.12 dimostra come passare gli argomenti di tipo valore come valori e come riferimenti (il Capitolo 7 descrive come passare gli argomenti di tipo riferimento come valori e come riferimenti). Il programma passa tre variabili di tipo valore (number1 number1, number2 e number3) in vari modi alle procedure SquareByValue (righe 39-45) e SquareByReference (righe 48-54). La parola chiave ByVal nell intestazione della procedura di SquareByValue (riga 39) indica che gli argomenti di tipo valore devono essere passati come valori. Quando la variabile number1 viene passata a SquareByValue (riga 13), una copia del valore memorizzato in number1 (2) viene passata alla procedura. Quindi, il valore di number1 nella procedura che effettua la chiamata (Main Main) non viene modificato quando il parametro number viene elevato al quadrato nella procedura SquareByValue (riga 42). La procedura SquareByReference usa la parola chiave ByRef (riga 48) per ricevere il suo parametro di tipo valore come riferimento. Quando Main chiama SquareByReference (riga 23), viene passato un riferimento al valore memorizzato in number2, che consente a SquareByReference di accedere direttamente al valore memorizzato nella variabile originale. Quindi, il valore memorizzato in number2 dopo l esecuzione di SquareByReference è uguale al valore finale del parametro number. Quando gli argomenti sono racchiusi fra parentesi tonde, una copia del valore dell argomento viene passato alla procedura, anche se l intestazione della procedura include la parola chiave ByRef. Quindi, il valore di number3 non cambia dopo che è stato passato a SquareByReference (riga 33) fra parentesi. Passare gli argomenti di tipo valore con la parola chiave ByRef è utile quando occorre che le procedure possano modificare direttamente i valori degli argomenti. Tuttavia, passare gli argomenti come riferimenti può compromettere la sicurezza dei dati, perché la procedura chiamata può modificare i dati del caller.

PROCEDURE 163 Una variabile tipo riferimento passata con la parola chiave ByVal viene passata effettivamente come riferimento, in quanto il valore che viene copiato è il riferimento per l oggetto. Sebbene Visual Basic consenta ai programmatori di utilizzare la parola chiave ByRef con i parametri tipo riferimento, di solito, non è necessario fare questo, tranne con il tipo String. Sebbene, tecnicamente, gli argomenti String siano riferimenti, tuttavia non possono essere modificati direttamente quando sono passati con la parola chiave ByVal, a causa di alcuni piccoli dettagli del tipo di dati String, che saranno descritti nel Capitolo 14. 1 Figura 6.12: ByRefTest.vb 2 Passare gli argomenti come riferimenti 3 4 Module modbyreftest 5 6 calcola il quadrato di tre valori; visualizza i risultati 7 Sub Main() 8 Dim number1 As Integer = 2 9 10 Console.WriteLine( Passing a value-type argument by value: ) 11 Console.WriteLine( Before calling SquareByValue, & _ 12 number1 is {0}, number1) 13 SquareByValue(number1) passa number1 come valore 14 Console.WriteLine( After returning from SquareByValue, & _ 15 number1 is {0} & vbcrlf, number1) 16 17 Dim number2 As Integer = 2 18 19 Console.WriteLine( Passing a value-type argument & _ 20 by reference: ) 21 Console.WriteLine( Before calling SquareByReference, & _ 22 number2 is {0}, number2) 23 SquareByReference(number2) passa number2 come riferimento 24 Console.WriteLine( After returning from & _ 25 SquareByReference, number2 is {0} & vbcrlf, number2) 26 27 Dim number3 As Integer = 2 28 29 Console.WriteLine( Passing a value-type argument & _ 30 by reference, but in parentheses: ) 31 Console.WriteLine( Before calling SquareByReference & _ 32 using parentheses, number3 is {0}, number3) 33 SquareByReference((number3)) passa number3 come valore 34 Console.WriteLine( After returning from & _ 35 SquareByReference, number3 is {0}, number3) 36 37 End Sub Main 38 39 quadrato di un argomento passato come valore (ByVal) 40 Sub SquareByValue(ByVal number As Integer) Figura 6.12 Applicazione di ByVal e ByRef per passare gli argomenti (continua)

164 CAPITOLO 6 41 Console.WriteLine( After entering SquareByValue, & _ 42 number is {0}, number) 43 number *= number 44 Console.WriteLine( Before exiting SquareByValue, & _ 45 number is {0}, number) 46 End Sub SquareByValue 47 48 quadrato di un argomento passato come riferimento (ByRef) 49 Sub SquareByReference(ByRef number As Integer) 50 Console.WriteLine( After entering SquareByReference & _ 51, number is {0}, number) 52 number *= number 53 Console.WriteLine( Before exiting SquareByReference & _ 54, number is {0}, number) 55 End Sub SquareByReference 56 57 End Module modbyreftest Passing a value-type argument by value: Before calling SquareByValue, number1 is 2 After entering SquareByValue, number is 2 Before exiting SquareByValue, number is 4 After returning from SquareByValue, number1 is 2 Passing a value-type argument by reference: Before calling SquareByReference, number2 is 2 After entering SquareByReference, number is 2 Before exiting SquareByReference, number is 4 After returning from SquareByReference, number2 is 4 Passing a value-type argument by reference, but in parentheses: Before calling SquareByReference using parentheses, number3 is 2 After entering SquareByReference, number is 2 Before exiting SquareByReference, number is 4 After returning from SquareByReference, number3 is 2 Figura 6.12 Applicazione di ByVal e ByRef per passare gli argomenti Collaudo e messa a punto 6.3 Quando gli argomenti sono passati come valori, le modifiche della copia della procedura chiamata non influenzano il valore della variabile originale. Questo evita potenziali effetti collaterali che potrebbero ostacolare lo sviluppo di corretti e affidabili sistemi software. Passate sempre gli argomenti di tipo valore come valori, a meno che non vogliate che la procedura chiamata possa modificare direttamente i dati del caller. Ingegneria del software 6.11 Sebbene le parole chiave ByVal e ByRef possano essere utilizzate per passare le variabili tipo riferimento come valori o come riferimenti, la procedura chiamata può manipolare direttamente la variabile tipo riferimento del caller in entrambi i casi. Di conseguenza, raramente è appropriato utilizzare ByRef con le variabili tipo riferimento. Questo particolare argomento sarà analizzato nel Capitolo 7.

PROCEDURE 165 6.10 Durata degli identificatori Nei precedenti capitoli abbiamo utilizzato gli identificatori per vari scopi, per esempio come nomi di variabili, classi e procedure definite dai programmatori. Gli identificatori contenuti in un programma possiedono altri attributi, tra cui la durata e la visibilità. La durata o ciclo di vita di un identificatore è il periodo durante il quale l identificatore esiste nella memoria. Alcuni identificatori esistono soltanto per un breve periodo di tempo, altri vengono ripetutamente creati e distrutti; altri ancora esistono per l intera esecuzione di un programma. La visibilità di un identificatore è la porzione del programma dove l identificatore può essere oggetto di riferimenti. Alcuni identificatori possono essere referenziati all interno dell intero programma, mentre altri soltanto in specifiche porzioni del programma. Questo paragrafo prende in esame la durata degli identificatori, mentre il prossimo parlerà della loro visibilità. Ingegneria del software 6.12 Quando un istruzione Return fornisce le informazioni di una procedura Function, le variabili di tipo valore sono sempre restituite come valori (una copia dei valori originali), mentre le variabili di tipo riferimento sono sempre restituite come riferimenti (viene restituito un riferimento a un oggetto). Gli identificatori che rappresentano delle variabili locali in una procedura (variabili e parametri dichiarati nel corpo della procedura) hanno una durata automatica. Le variabili con durata automatica vengono create quando il controllo del programma raggiunge la procedura dove sono dichiarate, esistono per tutto il tempo in cui è attiva la procedura e vengono distrutte quando la procedura termina (le variabili di una procedura possono essere dichiarate anche con la parola chiave Static; in questo caso, la variabile viene creata e inizializzata durante la prima esecuzione della procedura, che mantiene il suo valore fra le successive chiamate). Da questo momento in poi, faremo riferiremo a queste variabili usando il termine variabili automatiche o variabili locali. Le variabili dichiarate all interno di un modulo o di una classe, ma all esterno della definizione di una procedura, esistono finché la classe o il modulo che le contengono sono in memoria. Le variabili dichiarate in un modulo esistono durante l esecuzione del programma. Per default, una variabile dichiarata in una classe, come la classe Form per un applicazione Windows, è una variabile di istanza. Nel caso della classe Form, questo significa che la variabile viene creata quando la classe Form viene caricata in memoria ed esiste finché Form non sarà chiusa. Le variabili di istanza di una classe sono descritte nel Capitolo 8. Ingegneria del software 6.13 La durata automatica è un esempio del principo dei privilegi minimi, che stabilisce che ogni componente di un sistema deve godere dei diritti e dei privilegi che sono strettamente necessari per svolgere il suo compito. Questo consente di ridurre i rischi di errori accidentali nei sistemi. Perché mantenere in memoria variabili che non sono richieste? 6.11 Regole di visibilità La visibilità di una variabile, di un riferimento o metodo è la parte di programma in cui è possibile accedere all identificatore. Un identificatore può avere visibilità nella classe, nel modulo nel namespace e nel blocco.