Programmazione in Ada95

  • Upload
    markdv

  • View
    622

  • Download
    4

Embed Size (px)

DESCRIPTION

Guida pratica alla programmazione ADA95Sito utile: http://en.wikibooks.org/wiki/Ada_Programming

Citation preview

Claudio Marsan

Programmazione in Ada 95

Lavoro di maturit 2002 Liceo cantonale di Mendrisio

Dispense per la parte introduttiva del Lavoro di Maturit 2002, Liceo cantonale di Mendrisio.

ultima revisione: 11 marzo 2003

A Questo testo stato scritto dallautore con L TEX2.

Claudio Marsan Liceo cantonale di Mendrisio Via Agostino Maspoli CH6850 Mendrisio

e-mail: [email protected]

INDICE

1 Introduzione al linguaggio Ada 95 1.1 Introduzione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.1.1 Genesi . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.1.2 Dove viene usato Ada? . . . . . . . . . . . . . . . . . . 1.1.3 Specicazioni di Ada . . . . . . . . . . . . . . . . . . . . 1.2 Alcune caratteristiche di Ada . . . . . . . . . . . . . . . . . . . 1.3 Primi passi con Ada 95 . . . . . . . . . . . . . . . . . . . . . . 1.3.1 Il pi semplice programma in Ada 95 . . . . . . . . . . 1.3.2 Hello, World! . . . . . . . . . . . . . . . . . . . . . . . . 1.3.3 Come creare un programma scritto in Ada 95? . . . . . 1.3.4 Input e output . . . . . . . . . . . . . . . . . . . . . . . 1.3.5 Un programma un po pi complicato . . . . . . . . . . 1.3.6 Identicatori . . . . . . . . . . . . . . . . . . . . . . . . 1.3.7 Variabili e costanti . . . . . . . . . . . . . . . . . . . . . 1.3.8 Tipi di dati . . . . . . . . . . . . . . . . . . . . . . . . . 1.3.9 Il tipo INTEGER . . . . . . . . . . . . . . . . . . . . . . 1.3.10 Il tipo FLOAT . . . . . . . . . . . . . . . . . . . . . . . 1.3.11 I tipi enumerativi . . . . . . . . . . . . . . . . . . . . . . 1.3.12 Alcuni attributi utili . . . . . . . . . . . . . . . . . . . . 1.3.13 Flusso di controllo . . . . . . . . . . . . . . . . . . . . . 1.4 Istruzioni condizionali . . . . . . . . . . . . . . . . . . . . . . . 1.4.1 Listruzione if ... then ... end if; . . . . . . . . 1.4.2 Listruzione if ... then ... else ... end if; . 1.4.3 Operatori relazionali . . . . . . . . . . . . . . . . . . . . 1.4.4 Operatori logici . . . . . . . . . . . . . . . . . . . . . . . 1.4.5 Listruzione if ... then ... elsif ... end if; 1.4.6 Selezione multipla . . . . . . . . . . . . . . . . . . . . . 1.5 Istruzioni di ripetizione . . . . . . . . . . . . . . . . . . . . . . 1.5.1 Cicli semplici . . . . . . . . . . . . . . . . . . . . . . . . 1.5.2 Il ciclo for . . . . . . . . . . . . . . . . . . . . . . . . . . 1.5.3 Il ciclo while . . . . . . . . . . . . . . . . . . . . . . . . 1.5.4 Listruzione exit . . . . . . . . . . . . . . . . . . . . . . 1.5.5 Cicli nidicati . . . . . . . . . . . . . . . . . . . . . . . . 1.6 Listruzione null . . . . . . . . . . . . . . . . . . . . . . . . . . 1.7 Listruzione goto . . . . . . . . . . . . . . . . . . . . . . . . . . 1.8 Blocchi di istruzioni . . . . . . . . . . . . . . . . . . . . . . . . iii

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

1 1 1 2 2 3 4 4 5 6 7 9 10 13 14 14 23 29 32 35 35 35 36 37 38 38 40 42 43 44 45 47 49 51 52 53

iv 1.9

INDICE Qualche cenno sugli array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 63 63 64 66 70 75 76 77 78 79 82 85 88 92 95 98 101 101 103 106 107 110 110 113 116 117 119 120 121 124 126 127 128 131 132 135 135 136 137 138 146 147 148 149 151 152 153 156 157 Liceo cantonale di Mendrisio, 2002

2 Procedure e funzioni in Ada 95 2.1 Introduzione . . . . . . . . . . . . . . . . . . . . . 2.2 Funzioni matematiche predenite . . . . . . . . . 2.3 Funzioni . . . . . . . . . . . . . . . . . . . . . . . 2.4 Procedure . . . . . . . . . . . . . . . . . . . . . . 2.5 Sovraccaricare funzioni e procedure . . . . . . . . 2.6 Parametri di default . . . . . . . . . . . . . . . . 2.7 Sottoprogrammi ricorsivi . . . . . . . . . . . . . . 2.8 Esempi di algoritmi . . . . . . . . . . . . . . . . . 2.8.1 Calcolo del massimo comune divisore . . . 2.8.2 Divisione per tentativi . . . . . . . . . . . 2.8.3 Il crivello di Eratostene . . . . . . . . . . 2.8.4 Lalgoritmo di Sundaram . . . . . . . . . 2.8.5 Il metodo della fattorizzazione di Fermat 2.8.6 Il metodo di bisezione . . . . . . . . . . . 2.8.7 Il metodo di Newton . . . . . . . . . . . . 3 Tipi di dati in Ada 95 3.1 Astrazione dei dati . . . . . . . . . . 3.2 Ancora sui tipi interi . . . . . . . . . 3.2.1 Input e output di interi . . . 3.2.2 Tipi interi non segnati . . . . 3.3 Ancora sui tipi reali . . . . . . . . . 3.3.1 Numeri reali a virgola mobile 3.3.2 Attributi per i numeri reali in 3.3.3 Numeri reali a virgola ssa . 3.4 Tipi discreti . . . . . . . . . . . . . . 3.5 Sottotipi . . . . . . . . . . . . . . . . 3.6 Array . . . . . . . . . . . . . . . . . 3.6.1 Array vincolati . . . . . . . . 3.6.2 Array non vincolati . . . . . 3.6.3 Array multidimensionali . . . 3.6.4 Array di array . . . . . . . . 3.7 Record . . . . . . . . . . . . . . . . . 3.7.1 Array di record . . . . . . . . 3.7.2 Record con parte variante . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . virgola mobile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . .

4 Files in Ada 95 4.1 Il concetto di le . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.2 Files di testo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.2.1 Creazione, apertura e chiusura di un le di testo . . . . . 4.2.2 Accesso agli elementi di un le di testo . . . . . . . . . . . 4.2.3 Altre manipolazioni possibili con i les di testo . . . . . . 4.3 Files binari . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.3.1 Creazione, apertura e chiusura di un le binario . . . . . 4.3.2 Accesso agli elementi di un le binario sequenziale . . . . 4.3.3 Manipolazione di les binari sequenziali . . . . . . . . . . 4.3.4 Accesso agli elementi di un le binario ad accesso diretto 4.3.5 Manipolazione di les binari ad accesso diretto . . . . . . 4.4 Altre osservazioni sulluso dei les . . . . . . . . . . . . . . . . . 5 Gestione delle eccezioni in Ada 95 Claudio Marsan

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

INDICE 5.1 5.2 5.3 5.4 5.5 5.6 Introduzione . . . . . . . . . . . . . . . Eccezioni predenite . . . . . . . . . . Trattamento di uneccezione . . . . . . Dichiarazione di uneccezione . . . . . Sollevare e propagare uneccezione . . Ancora sul trattamento delle eccezioni . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

v 157 157 161 165 166 166 171 171 172 173 173 176 182 183 185 192 196 197 208 210 213 221 221 228 230 233 241 241 242 243 245 246 248 253 259 259 259 261 264 265 265 267 269 270 271 287

6 Packages in Ada 95 6.1 Introduzione . . . . . . . . . . . . . . . . . . . . . . . . . . 6.2 Specicazione di un package . . . . . . . . . . . . . . . . . 6.3 Lambiente di programmazione di Ada 95 . . . . . . . . . 6.4 Uso dei packages . . . . . . . . . . . . . . . . . . . . . . . 6.5 Il corpo di un package . . . . . . . . . . . . . . . . . . . . 6.6 Un package per trattare i numeri razionali . . . . . . . . . 6.6.1 Costruzione del package Long_Integer_Math_Lib 6.6.2 Il package Rational_Numbers . . . . . . . . . . . . 6.6.3 Il package Rational_Numbers_IO . . . . . . . . . . 6.6.4 Il programma di test . . . . . . . . . . . . . . . . . 6.7 I packages disponibili in Ada 95 . . . . . . . . . . . . . . 6.8 Sottoprogrammi separati e in biblioteca . . . . . . . . . . 6.9 Paradigma modulare . . . . . . . . . . . . . . . . . . . . . 6.10 Astrazione dei tipi di dati . . . . . . . . . . . . . . . . . . 7 Genericit in Ada 95 7.1 Dichiarazioni e attualizzazioni . . . . 7.2 Tipi parametri . . . . . . . . . . . . 7.3 Parametri funzionali . . . . . . . . . 7.4 Un package per i vettori dello spazio

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

8 Strutture di dati dinamiche 8.1 Introduzione . . . . . . . . . . . . . . . . . . 8.2 Dichiarazione di tipi puntatore . . . . . . . 8.3 Lallocatore new . . . . . . . . . . . . . . . . 8.4 Rappresentazione schematica dei puntatori 8.5 Accesso alle variabili puntate . . . . . . . . 8.6 Assegnazioni . . . . . . . . . . . . . . . . . 8.7 Liste concatenate . . . . . . . . . . . . . . . 8.8 Alberi . . . . . . . . . . . . . . . . . . . . . 8.8.1 Denizione . . . . . . . . . . . . . . 8.8.2 Alberi binari . . . . . . . . . . . . . 8.8.3 Ordinamento con albero binario . . 8.9 Pile di interi dinamiche . . . . . . . . . . . 9 Alcuni metodi di ordinamento 9.1 Ordinamento per selezione . . 9.2 Ordinamento a bolle . . . . . 9.3 Ordinamento per inserzione . 9.4 Quick sort . . . . . . . . . . . 9.5 Ecienza . . . . . . . . . . . Bibliograa

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

Liceo cantonale di Mendrisio, 2002

Claudio Marsan

vi

INDICE

Claudio Marsan

Liceo cantonale di Mendrisio, 2002

CAPITOLO 1 Introduzione al linguaggio Ada 951.1 Introduzione

Ada un linguaggio di programmazione evoluto, originariamente sponsorizzato dal DoD (Department of Defense, ossia Ministero della Difesa degli Stati Uniti ) per essere utilizzato nellarea applicativa dei sistemi embedded (un sistema detto embedded quando il computer inserito ed parte integrante in un processo operativo pi complesso come, per esempio, una fabbrica di prodotti chimici, un missile oppure un impianto di lavaggio industriale).

1.1.1

Genesi

Nel 1974 il DoD si accorse che i costi per lo sviluppo di software erano troppo elevati e la parte maggiore dei costi era dovuta ai sistemi embedded. Analizzando in profondit i linguaggi di programmazione emerse che il Cobol era il linguaggio standard per le elaborazioni gestionali e che il Fortran era lequivalente per il calcolo scientico e tecnico. Nel campo dei sistemi embedded il numero dei linguaggi utilizzati (e dei loro dialetti!) era enorme (qualche centinaio!), provocando cos elevate spese per compilatori inutili e per le attivit di addestramento e di manutenzione necessarie a causa della mancanza di uno standard. Si decise cos, in attesa di avere un unico linguaggio di programmazione, di approvare e introdurre alcuni linguaggi: CMS2Y, CMS2M, SPL/1, TACPOL, JOVIAL J3, JOVIAL J73 e, ovviamente, Cobol e Fortran. Nel 1975 il DoD decise di uniformare i linguaggi di programmazione e richiese la progettazione di un linguaggio unico che potesse essere utilizzato per applicazioni di vario tipo (scientiche, commerciali, per la gestione di sistemi in tempo reale e di sistemi di comando). Nessuno fra i linguaggi esistenti era abbastanza completo per soddisfare le richieste del DoD. Nel 1977 fu cos pubblicata la lista delle caratteristiche che il nuovo linguaggio doveva avere. I linguaggi esistenti furono divisi in tre categorie cos classicabili: inadatto: vi rientravano i linguaggi superati o destinati ad altre aree applicative, e quindi da non prendere in ulteriore considerazione (per esempio: Fortran e Coral 66); non inadatto: vi rientravano quei linguaggi che, pur non essendo considerati soddisfacenti allo stato attuale, presentavano alcune caratteristiche interessanti come possibili elementi di studio per lo sviluppo del nuovo linguaggio (vedi RTL/2 e Lis); raccomandato come punto di partenza: vi rientravano tre linguaggi: Pascal, PL1 e Algol 68, che erano considerati possibili basi di partenza per la progettazione del nuovo linguaggio. 1

2

CAPITOLO 1. INTRODUZIONE AL LINGUAGGIO ADA 95

Delle 17 proposte pervenute dagli Stati Uniti e dallEuropa ne vennero scelte quattro, alle quali vennero assegnate dei colori per garantire lanonimato: CII Honeywell Bull (verde); Intermetrics (rosso); Softech (blu); SRI International (giallo). I quattro linguaggi di programmazione scelti vennero sottoposti a vari esami in tutto il mondo e nel 1978 restarono in lizza solo due candidati (il rosso e il verde). Nel 1979 il verde fu decretato vincitore del concorso. Il linguaggio prescelto era stato progettato da un gruppo di ricercatori francesi della CII Honeywell Bull, guidati da Jean Ichbiah. Il DoD annunci poi che il linguaggio prescelto si sarebbe chiamato Ada, in onore di quella che considerata il primo programmatore della storia: Augusta Ada Byron, contessa di Lovelace (18151851), glia di Lord Byron e assistente di Charles Babbage. Nel 1980, dopo vari miglioramenti in alcune parti, venne rilasciata la prima versione denitiva del linguaggio: essa fu proposta allANSI (American National Standards Institute) come standard. Per il lavoro di standardizzazione ci vollero due anni e varie modiche di piccola entit. Nel gennaio 1983 fu pubblicato il manuale di riferimento (norma ANSI) che den cos uno standard, accettato nel 1987 anche dallISO (International Standards Organization). Nel 1991 pi di 400 compilatori Ada erano stati validati, ossia avevano passato un test formato da una serie di migliaia di piccoli programmini (ACVC, Ada Compiler Validation Capability), progettati per valutare la conformit con lo standard. Ci garantisce lestrema portabilit dei programmi Ada, ossia la possibilit di compilare lo stesso programma con un altro compilatore o su unaltra macchina senza dover riscrivere o modicare del codice. Nel 1988 inizi un processo di revisione che doveva permettere di estendere il linguaggio: il progetto venne denominato Ada 9X, dove con 9X si intendeva che il processo di revisione doveva essere terminato negli anni Novanta. Nel 1995 venne cos denito un nuovo standard: Ada95 (norme ANSI e ISO).

1.1.2

Dove viene usato Ada?

Ada non rimasto connato nel DoD, ma usato anche: nei computer di bordo di quasi tutti gli aerei commerciali; in quasi tutti i sistemi di controllo del traco aereo; per il controllo di treni ad alta velocit e metropolitane; in applicazioni bancarie per il trasferimento di fondi; per il controllo di satelliti per la comunicazione e per la navigazione; in robotica industriale, elettronica medica, telecomunicazioni, . . . Si pu quindi vedere dagli esempi citati che Ada un linguaggio utilizzato soprattutto per lo sviluppo di applicazioni molto importanti, complesse e nelle quali richiesto un alto grado di sicurezza.

1.1.3

Specicazioni di Ada

Le specicazioni di Ada furono ssate per: rendere i programmi leggibili e adabili; Claudio Marsan Liceo cantonale di Mendrisio, 2002

1.2. ALCUNE CARATTERISTICHE DI ADA facilitare il loro sviluppo e la loro manutenzione; fare della programmazione unattivit umana; rendere i programmi ecaci; consentire una grande portabilit dei programmi.

3

Queste specicazioni furono ssate nello standard del 1983 (si parla cos di Ada 83). Questo standard denisce: ci che permesso in Ada; ci che non permesso in Ada; ci che lasciato libero al compilatore, ssando comunque dei limiti a tale libert. Ogni compilatore deve essere sottoposto ad un processo di validazione, processo che ha lintenzione di controllare che: i programmi Ada siano tradotti ed eseguiti correttamente; i programmi non conformi allo standard Ada siano riutati; gli scarti di un programma rispetto allo standard facciano parte degli scarti autorizzati e siano realizzati nella maniera descritta nello standard; le unit predenite (input/output, . . . ) siano fornite e siano conformi allo standard. Lo standard assicura cos che leetto di un programma scritto in Ada sia noto e identico (entro gli scarti permessi) per ogni implementazione del linguaggio! Un compilatore pu chiamarsi compilatore Ada solo dopo aver passato con successo il processo di validazione. La qualica di compilatore Ada vale solo per un anno; dopo un anno richiesta una nuova validazione!

1.2

Alcune caratteristiche di Ada

Ada un linguaggio algoritmico moderno, utilizzabile per applicazioni in campi diversi. Esso propone le facilitazioni presenti in linguaggi classici come il Pascal, ma anche altre pi speciche a certi campi particolari: le istruzioni di controllo: if, case, while, for, loop, exit, return, goto; richiamo di procedure; richiesta di rendezvous per la sincronizzazione dei task. le strutture che consentono la modularit: blocchi; procedure e funzioni; package; procedure, funzioni e package generici. le strutture concorrenti : processi chiamati task ; rendezvous tra due task. Liceo cantonale di Mendrisio, 2002 Claudio Marsan

4 la gestione delle eccezioni;

CAPITOLO 1. INTRODUZIONE AL LINGUAGGIO ADA 95

lorganizzazione dei dati per tipo: tipi scalari: interi, reali, booleani, caratteri, enumerativi; tipi strutturati: array, stringhe, record ; puntatori; tipi privati. il concetto di sottotipo; il calcolo numerico. Ada propone il concetto di unit di compilazione. Ogni unit pu essere compilata separatamente dalle altre a condizione che tutte quelle che usa siano gi state compilate; conseguentemente la compilazione di un progetto deve farsi secondo un certo ordine. Sono unit di compilazione: le dichiarazioni di procedure e funzioni; il corpo di procedure e funzioni; la dichiarazione di package; il corpo dei package; le dichiarazioni di unit generiche; le istanziazioni di unit generiche; il corpo dei task. La biblioteca o libreria Ada contiene tutte le unit gi compilate ad un dato momento e, in ogni caso, le unit predenite. La biblioteca Ada pu avere anche delle sottolibrerie (struttura gerarchica ad albero). Ogni implementazione seria di Ada permette la manipolazione della biblioteca (inserimento, sostituzione, eliminazione di unit) tale da garantire una ricompilazione automatica delle unit non aggiornate e di quelle da loro dipendenti. Da notare che le dipendenze non si dichiarano in modo esplicito sulla riga di comando del compilatore o del linker, ma sono ricavate dalle istruzioni with delle singole unit.

1.31.3.1

Primi passi con Ada 95Il pi semplice programma in Ada 95

Quello che segue il pi semplice programma che si pu scrivere in Ada 95: cos semplice che non fa nulla! procedure Nulla is begin null; end Nulla; Nel prossimo paragrafo vedremo un programma in Ada 95 che fa qualcosa pi di nulla! Claudio Marsan Liceo cantonale di Mendrisio, 2002

1.3. PRIMI PASSI CON ADA 95

5

1.3.2

Hello, World!

Tradizionalmente, quando si inizia a studiare un linguaggio di programmazione, si inizia a scrivere un programma che visualizza sullo schermo la scritta Hello, World!. Ecco la versione in Ada 95 di tale programma (nota: i numeri di linea servono solo come riferimento, non fanno cio parte del programma e dunque non vanno scritti): 01 02 03 04 05 06 07 08 09 10 11 12 -----Nome del file: HELLO.ADB Autore: Claudio Marsan Data dellultima modifica: 9 gennaio 2002 Scopo: scrive sul video la frase "Hello, world!" Testato con: Gnat 3.13p su Windows 2000

with Ada.Text_IO; procedure Hello is begin Ada.Text_IO.Put(Item => "Hello, World!"); end Hello;

Analizziamo brevemente il programma. Le linee 0105 iniziano con due trattini (): esse sono trattate come linee di commento. possibile usare i commenti anche dopo unistruzione. Un commento si estende no alla ne di una riga. Le linee 06 e 08 sono bianche: il compilatore Ada permettere luso di linee bianche per aumentare la leggibilit di un programma. La linea 07 la linea dimportazione: essa, in questo caso, serve per richiamare il package Ada.Text_IO che contiene le procedure necessarie per linput e loutput di caratteri e stringhe (tale package fornito con il compilatore Ada). La linea 09 la linea di intestazione del programma: il nome che appare dopo la parola riservata procedure importante perch quello che deve essere specicato in fase di link (consiglio: fare in modo che tale nome coincida con il nome del le, per non avere inutili complicazioni). La linea 10 indica linizio del corpo della procedura che contiene le istruzioni eseguibili del programma. La linea 11 listruzione necessaria per visualizzare sullo schermo Hello, World!. Il nome Ada.Text_IO.Put da intendere nel modo seguente: il comando Put che serve per visualizzare una stringa di caratteri da prendere dal package Ada.Text_IO. possibile fare la stessa cosa senza dover continuamente premettere Ada.Text_IO. alle procedure di input/output, ma rinunceremo a questa opportunit. La linea 12 termina il programma. Possiamo notare che ogni istruzione termina con un punto e virgola e che dopo la linea di intestazione e dopo begin non bisogna mettere il punto e virgola (esse non sono infatti considerate istruzioni!). Osservazione 1.3.1 una buona abitudine quella di usare i commenti; in particolare consigliabile inserire il nome del le che contiene il programma, il nome dellautore, cosa fa il programma, la data dellultima modica e con quale sistema operativo il programma stato testato. Osservazione 1.3.2 Tutti i package standard forniti con il compilatore Ada 95 iniziano il loro nome con Ada seguito da un punto. Liceo cantonale di Mendrisio, 2002 Claudio Marsan

6

CAPITOLO 1. INTRODUZIONE AL LINGUAGGIO ADA 95

1.3.3

Come creare un programma scritto in Ada 95?

Dopo aver pensato e progettato un programma, bisogna passare alla sua realizzazione pratica, ossia bisogna iniziare il lavoro al computer. Generalmente (e ci vale per ogni linguaggio di programmazione) si distinguono le fasi seguenti: 1. La fase di edizione: si usa un programma chiamato editor (potrebbe essere, in ambiente MSWindows, Notepad o PFE oppure un qualsiasi programma di elaborazione testi che permetta di salvare in formato ASCII). 2. La fase di compilazione: si usa un programma, chiamato compiler (compilatore) che, letto un le ASCII, genera codice oggetto (ossia del codice comprensibile alla CPU) oppure, se vi sono errori di sintassi, genera dei messaggi derrore. Se il compilatore segnala errori bisogna tornare alla fase di edizione (nel peggiore dei casi: alla progettazione!), correggere gli errori, ricompilare, . . . 3. La fase di collegamento: si usa un programma, detto linker, che collega il le contenente il codice oggetto generato dal compilatore con eventuali librerie o altri programmi (potrebbero esserci errori anche in questa fase). Se tutto funziona per il verso giusto il linker genera un le eseguibile (in ambiente MSWindows un le con lestensione .exe). 4. La fase di esecuzione: per eseguire il programma basta, solitamente, scrivere il nome del le eseguibile creato dal linker nella linea di comando di una nestra di shell. In progetti complicati c anche la fase di debugging: per essa si usa un particolare programma, detto debugger, che permette di scoprire dove ci sono errori logici nel programma o nei suoi algoritmi, dove il programma non eciente, dove il programma perde molto tempo in esecuzione, ... Tutte le operazioni appena descritte vanno eseguite da una linea di comando. Negli ultimi anni tuttavia si sono diusi gli IDE (Integrated Development Environment, ossia: ambiente di sviluppo integrato) che permettono di aumentare la produttivit del programmatore ma anche di fargli prendere delle brutte abitudini (per esempio: prova, se non va bene riprova!). In un ambiente di sviluppo integrato abbiamo, nello stesso programma, un editor (molto spesso perno sensibile al linguaggio di programmazione, ossia: riconosce le parole riservate, le strutture del linguaggio, . . . ), il compilatore, il linker e il debugger, nonch altri strumenti (per esempio una guida in linea sul linguaggio): cos possibile eseguire tutte le fasi descritte prima senza lasciare mai lambiente di sviluppo integrato, magari cliccando su delle icone (solitamente gli IDE hanno uninterfaccia graca e consentono luso del mouse). Noi programmeremo in Ada 95 in ambiente MSWindows, usando il compilatore della GNAT (versione 3.13p). Ad esso abbinato un ambiente di sviluppo integrato, AdaGIDE, molto facile e intuitivo da usare. Esempio 1.3.1 Ammettiamo di voler realizzare il programma Hello, descritto nel paragrafo precedente, in ambiente MSWindows. Ecco le operazioni da eseguire: 1. lanciare lambiente di sviluppo integrato AdaGIDE; 2. digitare il codice del programma (in caso di errori di battitura si pu correggere usando le stesse combinazioni di tasti dei pi comuni programmi dellambiente MSWindows); 3. salvare il le con il nome HELLO.ADB; 4. compilare il le cliccando sullapposita icona (verranno creati il le di testo HELLO.ALI e il le oggetto HELLO.O); 5. correggere eventuali errori nch il compilatore non segnala pi errori; 6. lanciare il linker cliccando sullapposita icona (verr creato il le HELLO.EXE); Claudio Marsan Liceo cantonale di Mendrisio, 2002

1.3. PRIMI PASSI CON ADA 95 7. eseguire il programma cliccando sullapposita icona.

7

Visto che AdaGIDE crea diversi le conveniente creare un direttorio per ogni programma: sar pi facile mantenere pulito il proprio spazio disco. Osservazione 1.3.3 Come accennato in precedenza, il nome del le che contiene il programma deve avere lo stesso nome del programma; il nome del le sar poi completato dallestensione .ADB (Ada body) (altri compilatori richiedono lestensione .ADA). Con il compilatore GNAT ammessa anche lestensione .ADS (Ada specication), ma tratteremo questo pi avanti. Esercizio 1.3.1 Scrivere, compilare, correggere ed eseguire il programma Hello.

1.3.4

Input e output

Il package Ada.Text_IO contiene le procedure necessarie per linput e loutput di singoli caratteri (CHARACTER) e stringhe (STRING, una stringa una sequenza di caratteri). Alcune procedure del package sono (nota: la sintassi sar pi chiara in seguito, quando avremo studiato le procedure): procedure Put(Item : in Character); (visualizza un carattere sullo schermo, a partire dalla posizione corrente del cursore) procedure Put(Item : in String); (visualizza una stringa sullo schermo, a partire dalla posizione corrente del cursore) procedure Put_Line(Item : in String); (visualizza una stringa sullo schermo, a partire dalla posizione corrente del cursore, e sposta il cursore allinizio di una nuova linea) procedure New_Line(Spacing : in Positive_Count := 1); (scrive una riga vuota oppure il numero di righe vuote indicato) procedure Set_Line(To : procedure Set_Col(To : cata) in Positive_Count); (posiziona il cursore alla riga indicata) in Positive_Count); (posiziona il cursore alla colonna indi-

procedure Get(Item : out Character); (legge un carattere dato da tastiera e lo memorizza nella variabile Item) procedure Get(Item : out String); (legge una stringa di caratteri data da tastiera e la memorizza nella variabile Item) procedure Get_Line(Item : out String; Last : out Natural); (legge la sequenza di caratteri digitati prima di aver digitato il tasto , memorizza tale sequenza nella variabile Item e memorizza inoltre il numero di caratteri letti nella variabile Last) procedure Skip_Line(Spacing : in Positive_Count := 1); (salta la lettura di una intera riga oppure il numero di intere righe indicato) Per usare una delle procedure elencate sopra in un programma bisogna scrivere il nome della procedura, preceduto da Ada.Text_IO., e seguito dagli eventuali argomenti, scritti tra parentesi. Esempio 1.3.2 Mediante listruzione Ada.Text_IO.Get(Item => ch); il prossimo carattere digitato da tastiera sar letto nella variabile ch di tipo CHARACTER. Uno spazio bianco (blank ) conta come carattere, invece no! Esempio 1.3.3 Nel frammento di programma seguente si pu notare luso di alcune procedure del package Ada.Text_IO. Liceo cantonale di Mendrisio, 2002 Claudio Marsan

8

CAPITOLO 1. INTRODUZIONE AL LINGUAGGIO ADA 95 ... Ada.Text_IO.New_Line; Ada.Text_IO.Put(Item => "Ciao"); Ada.Text_IO.New_Line(Spacing => 3); ...

Un carattere va racchiuso tra apici quando argomento di una procedura o appare nella parte destra di unistruzione di assegnazione; le stringhe sono sequenze di caratteri (lettere, numeri, caratteri speciali) e vanno racchiuse tra virgolette quando sono argomento di una procedura o appaiono nella parte destra di unistruzione di assegnazione. Caratteri e stringhe saranno trattati pi avanti. Per evitare di scrivere in continuazione Ada.Text_IO. si potrebbe fare uso della clausola use, scrivendo, dopo with Ada.Text_IO;, la linea use Ada.Text_IO; Come detto in precedenza rinunciamo a tale opportunit per una maggiore chiarezza e qualicheremo ogni volta le procedure e le funzioni premettendo il nome del package da cui esse provengono! Molti programmatori Ada esperti ritengono pi vantaggioso qualicare tutti i riferimenti piuttosto che usare la clausola use. Volendo essere molto spicci il programma visto nel paragrafo precedente potrebbe addirittura essere riscritto nel modo seguente: with Ada.Text_IO; use Ada.Text_IO; procedure Hello is begin Put("Hello, World!"); end Hello; oppure, ancora in forma pi compatta: with Ada.Text_IO; use Ada.Text_IO; procedure Hello is begin Put("Hello, World!"); end Hello; Naturalmente siamo scandalizzati da un simile modo di procedere, poich non fa parte del bagaglio culturale del programmatore Ada il motto Mai scrivere due righe di codice quando se ne pu scrivere una sola! Esercizio 1.3.2 Scrivere un programma (due versioni: la prima non fa uso della clausola use, la seconda s) che visualizzi sullo schermo il vostro nome, cognome e indirizzo email, uno per riga, iniziando dalla decima colonna della quinta riga e mantenendo lallineamento a sinistra. Alla ne lasciare 5 righe vuote. Finora abbiamo visto esempi di output. Se vogliamo dare un input dobbiamo avere una variabile, di tipo adatto, nella quale memorizzare i dati che inseriamo. Vediamo un esempio nel quale si chiede di inserire un carattere. -----Nome del file: CARATTERE.ADB Autore: Claudio Marsan Data dellultima modifica: 15 gennaio 2002 Scopo: input e output di un carattere Testato con: Gnat 3.13p su Windows 2000

Claudio Marsan

Liceo cantonale di Mendrisio, 2002

1.3. PRIMI PASSI CON ADA 95 with Ada.Text_IO; procedure Carattere is ch : CHARACTER; -- ch una variabile di tipo carattere begin Ada.Text_IO.New_Line(Spacing => 2); Ada.Text_IO.Put(Item => "Dare un carattere: "); Ada.Text_IO.Get(Item => ch); Ada.Text_IO.New_Line; Ada.Text_IO.Put(Item => "Il carattere digitato e: "); Ada.Text_IO.Put(Item => ch); Ada.Text_IO.New_Line(Spacing => 2); Ada.Text_IO.Put_Line(Item => "Adesso scrivo una ""x"""); Ada.Text_IO.Put(Item => x); Ada.Text_IO.New_Line(Spacing => 2); end Carattere; Ecco loutput del programma:

9

Dare un carattere: A Il carattere digitato e: A Adesso scrivo una "x" x Osservazione 1.3.4 Per visualizzare il carattere in una stringa necessario scriverlo due volte consecutivamente.

1.3.5

Un programma un po pi complicato

Il seguente programma legge una misura di lunghezza in pollici e la trasforma in centimetri secondo lequivalenza 1 = 2.54 cm (anche in questo programma i numeri di riga servono solo per il successivo commento al programma e non devono essere digitate!): 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 -----Nome del file: POLLICI_CM.ADB Autore: Claudio Marsan Data dellultima modifica: 15 gennaio 2002 Scopo: converte pollici in centimetri Testato con: Gnat 3.13p su Windows 2000

with Ada.Text_IO; with Ada.Float_Text_IO; procedure Pollici_cm is -------------------------------------------- Dichiarazione di variabili e costanti -------------------------------------------cm_per_pollice : CONSTANT FLOAT := 2.54; pollici : FLOAT; Claudio Marsan

Liceo cantonale di Mendrisio, 2002

10

CAPITOLO 1. INTRODUZIONE AL LINGUAGGIO ADA 95

17 centimetri : FLOAT; 18 19 begin 20 ----------------------------------------21 -- Lettura della misura da trasformare -22 ----------------------------------------23 Ada.Text_IO.New_Line; 24 Ada.Text_IO.Put(Item => "Dare una misura in pollici: "); 25 Ada.Float_Text_IO.Get(Item => pollici); 26 27 -------------------------------------------28 -- Trasformazione da pollici a centimetri -29 -------------------------------------------30 centimetri := cm_per_pollice * pollici; 31 32 ----------------------------------33 -- Visualizzazione del risultato -34 ----------------------------------35 Ada.Text_IO.New_Line; 36 Ada.Text_IO.Put(Item => "Tale misura corrisponde a "); 37 Ada.Float_Text_IO.Put(Item => centimetri); 38 Ada.Text_IO.Put(Item => " centimetri."); 39 Ada.Text_IO.New_Line; 40 end Pollici_cm; Grazie alla riga 07 possiamo usare le procedure di input/output per caratteri e stringhe; grazie alla riga 08 possiamo usare le procedure di input/output per i numeri reali (in Ada i numeri reali si chiamano FLOAT). La riga 15 contiene la denizione della costante cm_per_pollice di tipo FLOAT: per il momento possiamo ritenere cm_per_pollice come un oggetto che vale 2.54 e che non pu modicare il suo valore nel programma. Le righe 16 e 17 deniscono due variabili di tipo FLOAT: esse servono per contenere dei valori reali e possono modicare il loro contenuto nel programma. Con la riga 25 si memorizza nella variabile pollici il numero reale digitato dallutente. La riga 30 contiene unistruzione di assegnazione: alla variabile centimetri viene assegnato il valore del prodotto della costante cm_per_pollice con la variabile pollici. Il simbolo := loperatore di assegnazione. Con la riga 37 si pu scrivere il contenuto della variabile centimetri sullo schermo. Da notare che la procedura si chiama Put, come quella usata per stampare un carattere o una stringa; tuttavia essa proviene dal package Ada.Float_Text_IO e non dal package Ada.Text_IO. Ecco un esempio duso del programma: Dare una misura in pollici: 10.0 Tale misura corrisponde a 2.54000E+01 centimetri.

Probabilmente ci saremmo aspettati la visualizzazione del risultato come 25.4; vedremo pi avanti perch non cos!

1.3.6

Identicatori

Un identicatore un nome usato per riferirsi ad ogni oggetto in Ada e deve soddisfare alcune rigide regole: Claudio Marsan Liceo cantonale di Mendrisio, 2002

1.3. PRIMI PASSI CON ADA 95 1. un identicatore deve iniziare con una lettera;

11

2. dopo la lettera iniziale lidenticatore pu essere composto da lettere, cifre e caratteri di sottolineatura, nel numero desiderato, a patto che non ci siano due caratteri di sottolineatura consecutivi e che lultimo carattere non sia un carattere di sottolineatura; 3. Ada case insensitive, ossia non distingue tra lettere maiuscole e lettere minuscole; 4. non c limite alla lunghezza di un identicatore, ma ogni identicatore deve poter essere scritto su ununica riga (nota: la lunghezza minima di una riga in Ada di 200 caratteri); 5. spazi bianchi e caratteri speciali non sono ammessi come parte di un identicatore. Esercizio 1.3.3 Dire quali fra i seguenti identicatori valido in un programma Ada: x y__1 metri-sec X1 metri sec mETRiSec 1X metri_sec _metri_sec X_1 metri/sec x_Y_1_ MetriSec

Gli identicatori vanno scelti in modo sensato: essi dovrebbero avere un nome, possibilmente non troppo lungo (gli identicatori si scrivono pi volte allinterno di un programma!), che ricordi lo scopo o lazione dellidenticatore. Attenzione alle 69 parole riservate in Ada 95 poich esse non possono essere usate come nomi di identicatori: abort abs abstract accept access aliased all and array at begin body case constant declare delay delta digits do else elsif end entry exception exit for function generic goto if in is new not null return reverse select separate subtype tagged task terminate then type

of or others out package pragma private procedure protected raise range record rem renames requeue

until use when while with xor

limited loop mod

Solitamente si seguono le seguenti convenzioni: le parole riservate sono scritte in minuscolo; le variabili sono scritte con liniziale di ogni parola di cui sono composte in maiuscolo e tutte le altre lettere in minuscolo; i tipi di dati sono scritti completamente in maiuscolo; le costanti sono scritte completamente in maiuscolo; Liceo cantonale di Mendrisio, 2002 Claudio Marsan

12

CAPITOLO 1. INTRODUZIONE AL LINGUAGGIO ADA 95 i valori di enumerazione sono scritti completamente in maiuscolo; gli attributi sono scritti completamente in maiuscolo; i nomi di procedure sono scritti con liniziale di ogni parola di cui sono composte in maiuscolo e tutte le altre lettere in minuscolo; i nomi di funzioni sono scritti con liniziale di ogni parola di cui sono composte in maiuscolo e tutte le altre lettere in minuscolo; i nomi di package sono scritti con liniziale di ogni parola di cui sono composte in maiuscolo e tutte le altre lettere in minuscolo; i nomi di librerie sono scritti con liniziale di ogni parola di cui sono composte in maiuscolo e tutte le altre lettere in minuscolo

Esercizio 1.3.4 Cosa verr scritto sullo schermo eseguendo il programma seguente? -----Nome del file: COSA_FA.ADB Autore: Claudio Marsan Data dellultima modifica: 21 gennaio 2002 Scopo: esercizio sulloutput di un programma Testato con: Gnat 3.13p su Windows 2000

with Ada.Text_IO; procedure Cosa_fa is c, ch : CHARACTER; begin Ada.Text_IO.New_Line(Spacing => 2); Ada.Text_IO.Put_Line(Item => "Dare un carattere: "); Ada.Text_IO.Get(Item => c); Ada.Text_IO.New_Line; Ada.Text_IO.Set_Col(To => 5); Ada.Text_IO.Put(Item => "Dare un altro carattere: "); Ada.Text_IO.Get(Item => ch); Ada.Text_IO.Set_Line(To => 10); Ada.Text_IO.Set_Col(To => 12); Ada.Text_IO.Put(Item => c); Ada.Text_IO.Set_Col(To => 15); Ada.Text_IO.Put(Item => c); Ada.Text_IO.Set_Col(To => 18); Ada.Text_IO.Put(Item => C); Ada.Text_IO.Set_Col(To => 21); Ada.Text_IO.Put(Item => "C"); Ada.Text_IO.Set_Col(To => 24); Ada.Text_IO.New_Line(Spacing => 2); Ada.Text_IO.Put(Item => ch); Ada.Text_IO.Put_Line(Item => "ch"); Ada.Text_IO.New_Line; end Cosa_fa; Vericare poi con il calcolatore la vostra previsione. Claudio Marsan Liceo cantonale di Mendrisio, 2002

1.3. PRIMI PASSI CON ADA 95

13

1.3.7

Variabili e costanti

In Ada variabili e costanti sono detti oggetti. Ogni oggetto ha: un nome valido (vedi regole sugli identicatori); un valore. Possiamo immaginare una variabile come un contenitore: sul contenitore c unetichetta (nome della variabile) che permette di distinguere i vari contenitori e al suo interno c il contenuto (il valore della variabile). Prima di poter usare una variabile o una costante in un programma bisogna dichiararle, dopo lintestazione della procedura (nella cosiddetta parte dichiarativa). La dichiarazione di una variabile ha la forma seguente: nome_variabile : TIPO_VARIABILE; oppure, se abbiamo pi variabili dello stesso tipo: nome_var_1, nome_var_2, ... : TIPO_VARIABILE; Per esempio: ... 01 ch : CHARACTER; 02 lato, area, perimetro : FLOAT; 03 numero_avv_postale : INTEGER; ... Nella riga 01 abbiamo denito la variabile ch di tipo CHARACTER; nella riga 02 abbiamo denito le variabili lato, area e perimetro, tutte di tipo FLOAT (numeri reali); nella riga 03 abbiamo denito la variabile numero_avv_postale di tipo INTEGER (numero intero). Allinizio, quando si dichiara una variabile, essa ha un valore indenito (alcuni compilatori tuttavia pongono le variabili numeriche uguali a 0); si resta in questo stato no a che non le si d un valore allinterno del programma. In Ada tuttavia possibile assegnare, in fase di dichiarazione, un valore iniziale alle variabili. La sintassi la seguente: nome_variabile : TIPO_VARIABILE := espressione; oppure, se abbiamo pi variabili dello stesso tipo alle quali bisogna assegnare lo stesso valore iniziale: nome_var_1, nome_var_2, ... : TIPO_VARIABILE := espressione; Per esempio: ... 01 lato : FLOAT 02 perimetro : FLOAT 03 n, m : INTEGER ... := 12.3; := 4*lato; := 0;

Nella riga 01 abbiamo denito la variabile lato di tipo FLOAT e ad essa abbiamo assegnato il valore iniziale 12.3; nella riga 02 abbiamo denito la variabile perimetro e ad essa abbiamo assegnato il valore iniziale 4*lato; nella riga 03 abbiamo denito le variabili n e m di tipo INTEGER e le abbiamo inizializzate con il valore 0. Da notare che lordine della dichiarazione delle variabili importante: nellesempio sopra necessario denire prima lato di perimetro! Una costante pu pure essere vista come un contenitore con unetichetta e un contenuto: rispetto ad una variabile per il contenuto deve essere specicato nella dichiarazione e poi non pu pi essere modicato (possiamo pensare che il contenitore viene sigillato ermeticamente). Una costante si dichiara nel modo seguente: Liceo cantonale di Mendrisio, 2002 Claudio Marsan

14

CAPITOLO 1. INTRODUZIONE AL LINGUAGGIO ADA 95 nome_costante : CONSTANT TIPO_COSTANTE := espressione;

oppure nome_costante : CONSTANT := espressione_numerica; nel caso in cui si voglia dichiarare una costante numerica che sia utilizzabile poi in associazione con vari tipi numerici (in tal caso, a dipendenza dellinizializzazione, si dice che la costante di tipo universal_integer oppure universal_real). Per esempio: ... 01 NAP_Mendrisio : CONSTANT INTEGER := 6850; 02 PI_greco : CONSTANT := 3.1415926; 03 MB : CONSTANT := 1048576; ... Nella riga 01 abbiamo denito la costante NAP_Mendrisio di tipo INTEGER con il valore 6850; nella riga 02 abbiamo denito la costante PI_greco di tipo universal_real con il valore 3.1415926; nella riga 03 abbiamo denito la variabile MB di tipo universal_integer con il valore 1048576.

1.3.8

Tipi di dati

Il compito di un programma di manipolare oggetti dierenti. Spesso un oggetto rappresenta, in un programma, qualcosa che avviene nel mondo reale. Oggetti dierenti hanno propriet dierenti: in Ada si dice che tali oggetti sono di tipo diverso. Un tipo in Ada caratterizzato da: i valori che possono assumere gli oggetti appartenenti al tipo; le operazioni che si possono compiere con gli oggetti appartenenti al tipo. Per esempio per il tipo FLOAT i possibili valori sono, in principio, tutti i numeri reali e le operazioni sono le comuni operazioni matematiche come laddizione e la moltiplicazione. Osservazione 1.3.5 Bisogna prestare molta attenzione al fatto seguente: Ada un linguaggio che controlla molto attentamente il tipo dei dierenti oggetti. Oggetti di un certo tipo possono assumere solo valori accettabili per quel tipo (per esempio se lato una variabile di tipo FLOAT ad essa non pu essere assegnato un valore intero). Se da una parte questa caratteristica di Ada pu sembrare molto pedante, dallaltra parte aiuta a costruire programmi migliori e pi adabili. Ada un linguaggio fortemente tipizzato: oltre ai tipi standard predeniti (essi sono deniti nel package Standard presente in tutte le implementazioni di Ada e al quale si accede direttamente, senza dover far uso della clausola with, il programmatore pu denire dei propri tipi, anche molto complessi, per descrivere gli oggetti del suo programma.

1.3.9

Il tipo INTEGER

Il tipo INTEGER rappresenta il concetto matematico di numero intero. Dalla matematica noto che linsieme Z := {. . . , 3, 2, 1, 0, 1, 2, 3, . . .} dei numeri interi innito ma, essendo la memoria di un computer nita, potremo rappresentare solo un sottoinsieme nito di Z. Tale sottoinsieme dipende dal numero di bit che una macchina usa per memorizzare un intero: macchine diverse possono usare numeri di bit diversi (16, 32, 64). Per sapere i valori minimo e massimo degli interi si pu ricorrere agli attributi FIRST e, rispettivamente, LAST, che si usano come nellesempio seguente. Esempio 1.3.4 Questo programma visualizza sullo schermo il pi piccolo e il pi grande INTEGER che sa manipolare il vostro compilatore Ada 95: Claudio Marsan Liceo cantonale di Mendrisio, 2002

1.3. PRIMI PASSI CON ADA 95 ------Nome del file: LIMITI_INTEGER.ADB Autore: Claudio Marsan Data dellultima modifica: 21 gennaio 2002 Scopo: scrive sul video il pi piccolo e il pi grande fra gli interi rappresentabili Testato con: Gnat 3.13p su Windows 2000

15

with Ada.Text_IO, Ada.Integer_Text_IO; procedure Limiti_Integer is begin Ada.Text_IO.New_Line; Ada.Text_IO.Put(Item => "Il piu piccolo INTEGER e: "); Ada.Integer_Text_IO.Put(Item => INTEGERFIRST); Ada.Text_IO.New_Line; Ada.Text_IO.Put(Item => "Il piu grande INTEGER e: "); Ada.Integer_Text_IO.Put(Item => INTEGERLAST); Ada.Text_IO.New_Line; end Limiti_Integer; Louput che si ottiene usando il compilatore GNAT 3.13p su Windows 2000 il seguente: Il piu piccolo INTEGER e: -2147483648 Il piu grande INTEGER e: 2147483647 Da notare che 2147483647 = 231 1, ossia un intero viene rappresentato con 32 bit (1 bit serve per il segno). Oltre al tipo INTEGER sono dichiarati, nel package Standard, anche i seguenti tipi di dati interi (loccupazione in bit dipende dal compilatore e non prestabilita da nessuna delle norme richieste per la validazione di un compilatore Ada 95; i dati sono riferiti al compilatore GNAT 3.13p per Windows 95/NT/2000): SHORT_SHORT_INTEGER, 8 bit con segno; SHORT_INTEGER, 16 bit con segno; LONG_INTEGER, 32 bit con segno; LONG_LONG_INTEGER, 64 bit con segno. Gli attributi FIRST e LAST possono essere utilizzati anche per stabilire i limiti di questi tipi. Esempio 1.3.5 Questo programma visualizza sullo schermo il pi piccolo e il pi grande valore per i tipi interi predeniti nel package Standard (riferiti al vostro compilatore Ada 95): ------Nome del file: LIMITI_INTERI_PREDEFINITI.ADB Autore: Claudio Marsan Data dellultima modifica: 21 gennaio 2002 Scopo: scrive sul video il pi piccolo e il pi grande fra gli interi rappresentabili, per ognuno dei tipi interi predefiniti Testato con: Gnat 3.13p su Windows 2000

Liceo cantonale di Mendrisio, 2002

Claudio Marsan

16

CAPITOLO 1. INTRODUZIONE AL LINGUAGGIO ADA 95

with Ada.Text_IO, Ada.Short_Short_Integer_Text_IO, Ada.Short_Integer_Text_IO, Ada.Integer_Text_IO, Ada.Long_Integer_Text_IO, Ada.Long_Long_Integer_Text_IO; procedure Limiti_Interi_Predefiniti is begin Ada.Text_IO.New_Line; Ada.Text_IO.Put(Item => "Il piu piccolo SHORT_SHORT_INTEGER e: "); Ada.Short_Short_Integer_Text_IO.Put(Item => SHORT_SHORT_INTEGERFIRST); Ada.Text_IO.New_Line; Ada.Text_IO.Put(Item => "Il piu grande SHORT_SHORT_INTEGER e: "); Ada.Short_Short_Integer_Text_IO.Put(Item => SHORT_SHORT_INTEGERLAST); Ada.Text_IO.New_Line(Spacing => 2); Ada.Text_IO.Put(Item => "Il piu piccolo SHORT_INTEGER e: "); Ada.Short_Integer_Text_IO.Put(Item => SHORT_INTEGERFIRST); Ada.Text_IO.New_Line; Ada.Text_IO.Put(Item => "Il piu grande SHORT_INTEGER e: "); Ada.Short_Integer_Text_IO.Put(Item => SHORT_INTEGERLAST); Ada.Text_IO.New_Line(Spacing => 2); Ada.Text_IO.Put(Item => "Il piu piccolo INTEGER e: "); Ada.Integer_Text_IO.Put(Item => INTEGERFIRST); Ada.Text_IO.New_Line; Ada.Text_IO.Put(Item => "Il piu grande INTEGER e: "); Ada.Integer_Text_IO.Put(Item => INTEGERLAST); Ada.Text_IO.New_Line(Spacing => 2); Ada.Text_IO.Put(Item => "Il piu piccolo LONG_INTEGER e: "); Ada.Long_Integer_Text_IO.Put(Item => LONG_INTEGERFIRST); Ada.Text_IO.New_Line; Ada.Text_IO.Put(Item => "Il piu grande LONG_INTEGER e: "); Ada.Long_Integer_Text_IO.Put(Item => LONG_INTEGERLAST); Ada.Text_IO.New_Line(Spacing => 2); Ada.Text_IO.Put(Item => "Il piu piccolo LONG_LONG_INTEGER e: "); Ada.Long_Long_Integer_Text_IO.Put(Item => LONG_LONG_INTEGERFIRST); Ada.Text_IO.New_Line; Ada.Text_IO.Put(Item => "Il piu grande LONG_LONG_INTEGER e: "); Ada.Long_Long_Integer_Text_IO.Put(Item => LONG_LONG_INTEGERLAST); Ada.Text_IO.New_Line; end Limiti_Interi_Predefiniti; Ecco loutput del programma: Claudio Marsan Liceo cantonale di Mendrisio, 2002

1.3. PRIMI PASSI CON ADA 95

17

Il piu piccolo SHORT_SHORT_INTEGER e: -128 Il piu grande SHORT_SHORT_INTEGER e: 127 Il piu piccolo SHORT_INTEGER e: -32768 Il piu grande SHORT_INTEGER e: 32767 Il piu piccolo INTEGER e: -2147483648 Il piu grande INTEGER e: 2147483647 Il piu piccolo LONG_INTEGER e: -2147483648 Il piu grande LONG_INTEGER e: 2147483647 Il piu piccolo LONG_LONG_INTEGER e: -9223372036854775808 Il piu grande LONG_LONG_INTEGER e: 9223372036854775807

Sono permesse le seguenti operazioni per variabili dello stesso tipo intero (il risultato sempre un intero dello stesso tipo degli operandi): addizione: + sottrazione: moltiplicazione: * elevazione a potenza (attenzione: lesponente deve essere un numero naturale!): ** divisione: / resto: rem modulo: mod valore assoluto: abs Come in diversi linguaggi di programmazione la divisione presenta qualche problema: con a/b si ottiene la parte intera della divisione (per esempio: 15/7 = 2); con a rem b si ottiene il resto della divisione di a con b e tale resto ha sempre il segno di a; con a mod b si ottiene il resto della divisione di a con b e tale resto ha sempre il segno di b; vale: a = (a/b) * b + (a rem b); vale: a = b * n + (a mod b), dove n un numero intero. Esempio 1.3.6 Siano n e m variabili di tipo INTEGER. Allora dopo le istruzioni n := -15 rem 7; m := 15 rem (-7); il valore di n sar -1 (infatti: 15 = 27+(1)) e il valore di m sar 1 (infatti: 15 = 2(7)+1). Esempio 1.3.7 Siano n e m variabili di tipo INTEGER. Allora dopo le istruzioni n := 15 mod (-7); m := -15 mod 7; Liceo cantonale di Mendrisio, 2002 Claudio Marsan

18

CAPITOLO 1. INTRODUZIONE AL LINGUAGGIO ADA 95

il valore di n sar -6 (infatti: 15 = 3(7)+(6)) e il valore di m sar 6 (infatti: 15 = 37+6). Esempio 1.3.8 Con il seguente programma possiamo controllare i risultati delle operazioni di divisione: -----Nome del file: DIVISIONI.ADB Autore: Claudio Marsan Data dellultima modifica: 21 gennaio 2002 Scopo: operazioni di divisione Testato con: Gnat 3.13p su Windows 2000

with Ada.Text_IO, Ada.Integer_Text_IO; procedure Divisioni is a, b quoto modulo resto : : : : INTEGER; INTEGER; INTEGER; INTEGER;

begin Ada.Text_IO.New_Line; Ada.Text_IO.Put(Item => "Dai un intero a: "); Ada.Integer_Text_IO.Get(Item => a); Ada.Text_IO.Put(Item => "Dai un altro intero b: "); Ada.Integer_Text_IO.Get(Item => b); quoto := a / b; resto := a rem b; modulo := a mod b; Ada.Text_IO.Put(Item => "a/b = "); Ada.Integer_Text_IO.Put(Item => quoto); Ada.Text_IO.New_Line; Ada.Text_IO.Put(Item => "a mod b = "); Ada.Integer_Text_IO.Put(Item => modulo); Ada.Text_IO.New_Line; Ada.Text_IO.Put(Item => "a rem b = "); Ada.Integer_Text_IO.Put(Item => resto); Ada.Text_IO.New_Line; end Divisioni; Ecco un esempio di output del programma:

Dai un intero a: 5 Dai un altro intero b: 2 a/b = 2 a mod b = 1 a rem b = 1 Un altro esempio di output dello stesso programma:

Claudio Marsan

Liceo cantonale di Mendrisio, 2002

1.3. PRIMI PASSI CON ADA 95 Dai un intero a: 7 Dai un altro intero b: -2 a/b = -3 a mod b = -1 a rem b = 1

19

Osservazione 1.3.6 Loutput del programma precedente mal formattato, ossia ci sono troppi spazi tra il carattere = e gli interi che vengono visualizzati. Infatti, per default, gli interi vengono visualizzati occupando sempre lo spazio necessario per lintero che occupa pi spazio (nel caso degli INTEGER: 11 spazi) e premettendo degli spazi bianchi se necessario. Il programmatore pu scegliere di utilizzare, nella procedura Put, anche largomento opzionale Width che permette di formattare loutput di un intero indicando il numero di spazi che deve occupare. Per esempio con la riga seguente Ada.Integer_Text_IO.Put(Item => n, Width => 0); il valore della variabile n, di tipo INTEGER, verr visualizzato senza premettere alcuno spazio bianco. Esempio 1.3.9 Il programma seguente visualizza loutput di una variabile di tipo INTEGER secondo varie formattazioni: -----Nome del file: OUTPUT_INTEGER_FORMATTATO.ADB Autore: Claudio Marsan Data dellultima modifica: 21 gennaio 2002 Scopo: mostra la formattazione delloutput di INTEGER Testato con: Gnat 3.13p su Windows 2000

with Ada.Text_IO, Ada.Integer_Text_IO; procedure Output_Integer_Formattato is n : INTEGER; begin Ada.Text_IO.New_Line(Spacing Ada.Text_IO.Put(Item => "Dai Ada.Integer_Text_IO.Get(Item Ada.Text_IO.New_Line(Spacing

=> un => =>

2); numero di tipo INTEGER: "); n); 2);

Ada.Text_IO.Put(Item => "Hai digitato: "); Ada.Integer_Text_IO.Put(Item => n, Width => 0); Ada.Text_IO.New_Line; Ada.Text_IO.Put(Item => "Hai digitato: "); Ada.Integer_Text_IO.Put(Item => n, Width => 1); Ada.Text_IO.New_Line; Ada.Text_IO.Put(Item => "Hai digitato: "); Ada.Integer_Text_IO.Put(Item => n, Width => 2); Ada.Text_IO.New_Line; Ada.Text_IO.Put(Item => "Hai digitato: "); Liceo cantonale di Mendrisio, 2002 Claudio Marsan

20

CAPITOLO 1. INTRODUZIONE AL LINGUAGGIO ADA 95 Ada.Integer_Text_IO.Put(Item => n, Width => 3); Ada.Text_IO.New_Line; Ada.Text_IO.Put(Item => "Hai digitato: "); Ada.Integer_Text_IO.Put(Item => n, Width => 20); Ada.Text_IO.New_Line; Ada.Text_IO.Put(Item => "Hai digitato: "); Ada.Integer_Text_IO.Put(Item => n, Width => 11); Ada.Text_IO.New_Line;

Ada.Text_IO.Put(Item => "Hai digitato: "); Ada.Integer_Text_IO.Put(Item => n); Ada.Text_IO.New_Line; end Output_Integer_Formattato; Un esempio di output:

Dai un numero di tipo INTEGER: 23

Hai Hai Hai Hai Hai Hai Hai

digitato: 23 digitato: 23 digitato: 23 digitato: 23 digitato: digitato: digitato:

23 23 23

Un altro esempio di output:

Dai un numero di tipo INTEGER: -1999

Hai Hai Hai Hai Hai Hai Hai

digitato: digitato: digitato: digitato: digitato: digitato: digitato:

-1999 -1999 -1999 -1999 -1999 -1999 -1999

Loutput seguente mostra chiaramente che, qualora lo spazio previsto dal programmatore per visualizzare il valore di una variabile di tipo INTEGER insuciente, il valore verr visualizzato ugualmente in modo corretto:

Dai un numero di tipo INTEGER: 1234567890 Claudio Marsan Liceo cantonale di Mendrisio, 2002

1.3. PRIMI PASSI CON ADA 95

21

Hai Hai Hai Hai Hai Hai Hai

digitato: digitato: digitato: digitato: digitato: digitato: digitato:

1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890

Per garantire la portabilit di un programma sconsigliato luso del tipo INTEGER (come detto in precedenza i limiti per il tipo INTEGER dipendono dal tipo di macchina e/o dal compilatore Ada che si usa); invece meglio denire un proprio tipo di dato, con le limitazioni chiare. Ada permette di denire dei nuovi tipi di dati interi vincolati il cui dominio un intervallo di numeri interi. La sintassi la seguente: type nome_del_tipo is range minimo..massimo; Esempio 1.3.10 Con type Cifre is range 0..9; deniamo un tipo per manipolare le cifre: tale tipo potr assumere solo valori interi compresi tra 0 e 9 inclusi. Nel package Standard sono deniti i sottotipi interi seguenti: subtype NATURAL is INTEGER range 0..INTEGERLAST; subtype POSITIVE is INTEGER range 1..INTEGERLAST; In generale un sottotipo si denisce mediante la sintassi seguente: subtype S is T range minimo..massimo; dove S il nome del sottotipo, T il nome del tipo e minimo..massimo lintervallo dei valori ammessi. Con una simile dichiarazione S diventa un sottotipo di T; nessun nuovo tipo viene creato. Oggetti del sottotipo S sono anche del tipo T. conveniente usare i sottotipi quando con essi si ha una buona rappresentazione della realt e quando essi facilitano la ricerca di errori logici. Osservazione 1.3.7 Per il sottotipo S del tipo T si possono usare le procedure di input e output del tipo T. Consideriamo il seguente frammento di programma: ... N : NATURAL; P : POSITIVE; I : INTEGER; ... P := N + P; I := P - N; ...

01 02

Le istruzioni 01 e 02 sono ammesse poich tutte le variabili che intervengono sono di tipo intero; POSITIVE un sottoinsieme di NATURAL che, a sua volta, un sottoinsieme di INTEGER. Liceo cantonale di Mendrisio, 2002 Claudio Marsan

22

CAPITOLO 1. INTRODUZIONE AL LINGUAGGIO ADA 95

Esercizio 1.3.5 Scrivere un programma che chiede allutente un numero intero n di tre cifre, calcoli la somma dei cubi delle cifre di n e visualizzi poi tale somma sullo schermo. Presentiamo una possibile soluzione dellesercizio proposto: -----Nome del file: SOMMA_CUBI_DELLE_CIFRE.ADB Autore: Claudio Marsan Data dellultima modifica: 21 gennaio 2002 Scopo: somma i cubi delle cifre di un numero di tre cifre Testato con: Gnat 3.13p su Windows 2000

with Ada.Text_IO, Ada.Integer_Text_IO; procedure Somma_Cubi_delle_Cifre is subtype Tre_Cifre is INTEGER range 100..999; n : Tre_Cifre; n1, n2, n3 : INTEGER; somma : INTEGER; begin Ada.Text_IO.New_Line(Spacing => 2); Ada.Text_IO.Put(Item => "Dare un numero intero di 3 cifre: "); Ada.Integer_Text_IO.Get(Item => n); n1 := n2 := n3 := somma n / 100; -- centinaia (n / 10) mod 10; -- decine n mod 10; -- unita := n1**3 + n2**3 + n3**3;

Ada.Text_IO.New_Line(Spacing => 2); Ada.Text_IO.Put(Item => "La somma dei cubi delle cifre di "); Ada.Integer_Text_IO.Put(Item => n, Width => 0); Ada.Text_IO.Put(Item => " vale: "); Ada.Integer_Text_IO.Put(Item => somma, Width => 0); Ada.Text_IO.New_Line(Spacing => 2); end Somma_Cubi_delle_Cifre; Ecco un esempio di output del programma:

Dare un numero intero di 3 cifre: 329

La somma dei cubi delle cifre di 329 vale: 764

Se alla richiesta di input non diamo un numero di tre cifre otterremo il seguente messaggio derrore:

Dare un numero intero di 3 cifre: 25 Claudio Marsan Liceo cantonale di Mendrisio, 2002

1.3. PRIMI PASSI CON ADA 95

23

raised CONSTRAINT_ERROR : a-tiinio.ads:61

Osservazione 1.3.8 Da notare che grazie alla denizione subtype Tre_Cifre possiamo usare, senza problemi, le procedure Get e Put presenti nel package Integer_Text_IO. Se invece avessimo usato la denizione type Tre_Cifre avremmo dovuto fornire delle procedure per linput e loutput di variabili del nuovo tipo. Nella pratica quotidiana, per facilitare la lettura di numeri grandi, separiamo ogni blocco di tre cifre, partendo da destra e spostandoci verso sinistra, con un apice. In Ada non possibile usare lapice ma, per lo stesso scopo, si user il trattino di sottolineatura _. Esempio 1.3.11 In un programma Ada possibile scrivere il numero 1000000 (ossia: 1 000 000) come 1_000_000 (ma anche come 10_00_0_00).

1.3.10

Il tipo FLOAT

Dalla matematica noto che linsieme dei numeri reali R lunione dellinsieme dei numeri razionali Q (linsieme dei numeri che si possono rappresentare sotto forma di frazione con numeratore e denominatore interi) con linsieme dei numeri irrazionali (un numero irrazionale quando non possibile esprimerlo sotto forma di frazione con numeratore e denominatore interi; per esempio 2 e sono irrazionali). Linsieme R innito (pi che numerabile) e denso (ossia: tra due qualsiasi numeri reali ne esistono inniti altri); dunque impensabile poter rappresentare esattamente R con un tipo di dati. In Ada il tipo FLOAT (per oating point numbers, numeri in virgola mobile) rappresenta unapprossimazione del concetto matematico di numero reale (per la precisione: di numero razionale). Osservazione 1.3.9 Il separatore decimale il punto e non la virgola (in Ada si scriver cos 3.14159 e non 3,14159). Il package Ada.Float_Text_IO fornisce le procedure Get e Put per linput e loutput di variabili di tipo FLOAT. Come gi visto nel paragrafo 1.3.5 loutput di un FLOAT in forma esponenziale, forma che pu essere piuttosto scomoda in certune circostanze. Fortunatamente esistono tre argomenti opzionali (entrambi sono degli interi non negativi) per la procedura Put: 1. Fore: indica il numero di spazi riservati per la componente intera del numero, ossia per la parte che precede il punto decimale; il valore di default 2. 2. Aft: indica il numero di decimali per la componente decimale del numero, ossia indica il numero di cifre dopo il punto decimale; il valore di default dipende dalla macchina e/o dal compilatore Ada in uso, con il compilatore GNAT 3.13p su Windows 2000 vale 5. 3. Exp: indica il numero di spazi riservati per lesponente; Liceo cantonale di Mendrisio, 2002 Claudio Marsan

24

CAPITOLO 1. INTRODUZIONE AL LINGUAGGIO ADA 95 se il valore diverso da zero il valore della variabile verr visualizzato in notazione scientica (si dice che un numero reale positivo in notazione scientica quando il numero scritto nella forma k 10n , con k [1, 10[); uno spazio riservato per il segno dellesponente (anche il segno + viene rappresentato).

Riassumendo: un numero reale visualizzabile nel formato Fore . Aft E Exp se Exp diverso da zero, oppure nel formato Fore . Aft altrimenti (gli spazi bianchi fra le varie parti sono stati inseriti unicamente per facilitare la lettura del formato, in un programma non vanno mai inseriti!). Esempio 1.3.12 Se volessimo far stampare il valore approssimato di come 3.14159 dovremmo procedere come nel seguente frammento di programma: ... PI_GRECO : constant FLOAT := 3.14159; ... Ada.Text_IO.Put("Pi greco vale: "); Ada.Float_Text_IO.Put(Item => PI_GRECO, Fore => 1, Aft ... Le istruzioni ... x : FLOAT; ... Ada.Float_Text_IO.Put(x, 5, 4, 3); Ada.Float_Text_IO.Put(Item => x, Fore => 5, Aft => 4, Exp Ada.Float_Text_IO.Put(Item => x, Exp => 3, Fore => 5, Aft ...

=> 5, Exp

=> 0);

01 02 03

=> 3); => 4);

visualizzano tutte la variabile x con 5 spazi riservati prima del punto decimale, 4 spazi riservati dopo il punto decimale e tre spazi riservati per lesponente: nella 01 i parametri non sono qualicati e vengono riconosciuti per la loro posizione (il primo la variabile della quale bisogna visualizzare il valore, il secondo Fore, il terzo per Aft e il quarto per Exp); nelle righe 02 e 03 non ci sono problemi poich la qualicazione chiaricante e permette di scrivere i parametri nellordine voluto. Esempio 1.3.13 Il seguente programma illustra luso della formattazione delloutput con una variabile di tipo FLOAT: -----Nome del file: FLOAT_OUTPUT.ADB Autore: Claudio Marsan Data dellultima modifica: 21 gennaio 2002 Scopo: output formattato di FLOAT Testato con: Gnat 3.13p su Windows 2000

with Ada.Text_IO, Ada.Float_Text_IO; procedure Float_Output is

Claudio Marsan

Liceo cantonale di Mendrisio, 2002

1.3. PRIMI PASSI CON ADA 95 x : FLOAT := 3.1415926; begin Ada.Text_IO.New_Line(Spacing => 2); Ada.Text_IO.Put(Item => "Put(Item => x, Fore => 5, Ada.Float_Text_IO.Put(Item => x, Fore => 5, Aft => Ada.Text_IO.New_Line; Ada.Text_IO.Put(Item => "Put(Item => x, Fore => 1, Ada.Float_Text_IO.Put(Item => x, Fore => 1, Aft => Ada.Text_IO.New_Line; Ada.Text_IO.Put(Item => "Put(Item => x, Fore => 0, Ada.Float_Text_IO.Put(Item => x, Fore => 0, Aft => Ada.Text_IO.New_Line; Ada.Text_IO.Put(Item => "Put(Item => x): "); Ada.Float_Text_IO.Put(Item => x); Ada.Text_IO.New_Line; Ada.Text_IO.Put(Item => "Put(x, Aft => 2): "); Ada.Float_Text_IO.Put(Item => x, Aft => 2); Ada.Text_IO.New_Line; Ada.Text_IO.Put("Put(x, Fore => 1, Exp => 2): "); Ada.Float_Text_IO.Put(x, Fore => 1, Exp => 2); Ada.Text_IO.New_Line; end Float_Output; Loutput del programma il seguente:

25

Aft => 4, Exp => 2): "); 4, Exp => 2); Aft => 9, Exp => 4): "); 9, Exp => 4); Aft => 8, Exp => 0): "); 8, Exp => 0);

Put(Item => x, Fore => 5, Aft => 4, Exp => 2): 3.1416E+0 Put(Item => x, Fore => 1, Aft => 9, Exp => 4): 3.141592503E+000 Put(Item => x, Fore => 0, Aft => 8, Exp => 0): 3.14159250 Put(Item => x): 3.14159E+00 Put(x, Aft => 2): 3.14E+00 Put(x, Fore => 1, Exp => 2): 3.14159E+0 Sono deniti anche altri tipi di reali: SHORT_FLOAT: dovrebbe essere meno preciso di FLOAT; LONG_FLOAT: pi preciso e grande di FLOAT; LONG_LONG_FLOAT: ancora pi preciso e pi grande. Con i tipi SHORT_FLOAT, FLOAT, LONG_FLOAT e LONG_LONG_FLOAT sono utilizzabili, tra gli altri, i seguenti attributi: FIRST, per identicare il pi piccolo numero rappresentabile; LAST, per identicare il pi grande numero rappresentabile; DIGITS, per indicare il numero di cifre signicative del numero; SIZE, per stabilire loccupazione di memoria in bit. Luso di questi attributi analogo a quello per i numeri interi. Esempio 1.3.14 Il seguente programma illustra luso degli attributi spiegati sopra: Liceo cantonale di Mendrisio, 2002 Claudio Marsan

26 ------

CAPITOLO 1. INTRODUZIONE AL LINGUAGGIO ADA 95 Nome del file: LIMITI_FLOAT.ADB Autore: Claudio Marsan Data dellultima modifica: 23 gennaio 2002 Scopo: limiti per FLOAT e simili Testato con: Gnat 3.13p su Windows 2000

with Ada.Text_IO, Ada.Short_Float_Text_IO, Ada.Float_Text_IO, Ada.Long_Float_Text_IO, Ada.Long_Long_Float_Text_IO, Ada.Integer_Text_IO; procedure Limiti_Float is begin Ada.Text_IO.New_Line(Spacing => 2); Ada.Text_IO.Put(Item => "Il piu piccolo SHORT_FLOAT e: "); Ada.Short_Float_Text_IO.Put(Item => SHORT_FLOATFIRST); Ada.Text_IO.New_Line; Ada.Text_IO.Put(Item => "Il piu grande SHORT_FLOAT e: "); Ada.Short_Float_Text_IO.Put(Item => SHORT_FLOATLAST); Ada.Text_IO.New_Line; Ada.Text_IO.Put(Item => "Cifre significative di SHORT_FLOAT: "); Ada.Integer_Text_IO.Put(Item => SHORT_FLOATDIGITS, Width => 0); Ada.Text_IO.New_Line; Ada.Text_IO.Put(Item => "Bit occupati da uno SHORT_FLOAT: "); Ada.Integer_Text_IO.Put(Item => SHORT_FLOATSIZE, Width => 0); Ada.Text_IO.New_Line(Spacing => 2); Ada.Text_IO.Put(Item => "Il piu piccolo FLOAT e: "); Ada.Float_Text_IO.Put(Item => FLOATFIRST); Ada.Text_IO.New_Line; Ada.Text_IO.Put(Item => "Il piu grande FLOAT e: "); Ada.Float_Text_IO.Put(Item => FLOATLAST); Ada.Text_IO.New_Line; Ada.Text_IO.Put(Item => "Cifre significative di FLOAT: "); Ada.Integer_Text_IO.Put(Item => FLOATDIGITS, Width => 0); Ada.Text_IO.New_Line; Ada.Text_IO.Put(Item => "Bit occupati da un FLOAT: "); Ada.Integer_Text_IO.Put(Item => FLOATSIZE, Width => 0); Ada.Text_IO.New_Line(Spacing => 2); Ada.Text_IO.Put(Item => "Il piu piccolo LONG_FLOAT e: "); Ada.Long_Float_Text_IO.Put(Item => LONG_FLOATFIRST); Ada.Text_IO.New_Line;

Claudio Marsan

Liceo cantonale di Mendrisio, 2002

1.3. PRIMI PASSI CON ADA 95 Ada.Text_IO.Put(Item => "Il piu grande LONG_FLOAT e: "); Ada.Long_Float_Text_IO.Put(Item => LONG_FLOATLAST); Ada.Text_IO.New_Line; Ada.Text_IO.Put(Item => "Cifre significative di LONG_FLOAT: "); Ada.Integer_Text_IO.Put(Item => LONG_FLOATDIGITS, Width => 0); Ada.Text_IO.New_Line; Ada.Text_IO.Put(Item => "Bit occupati da un LONG_FLOAT: "); Ada.Integer_Text_IO.Put(Item => LONG_FLOATSIZE, Width => 0); Ada.Text_IO.New_Line(Spacing => 2); Ada.Text_IO.Put(Item => "Il piu piccolo LONG_LONG_FLOAT e: "); Ada.Long_Long_Float_Text_IO.Put(Item => LONG_LONG_FLOATFIRST); Ada.Text_IO.New_Line; Ada.Text_IO.Put(Item => "Il piu grande LONG_LONG_FLOAT e: "); Ada.Long_Long_Float_Text_IO.Put(Item => LONG_LONG_FLOATLAST); Ada.Text_IO.New_Line; Ada.Text_IO.Put(Item => "Cifre significative di LONG_LONG_FLOAT: "); Ada.Integer_Text_IO.Put(Item => LONG_LONG_FLOATDIGITS, Width => 0); Ada.Text_IO.New_Line; Ada.Text_IO.Put(Item => "Bit occupati da un LONG_LONG_FLOAT: "); Ada.Integer_Text_IO.Put(Item => LONG_LONG_FLOATSIZE, Width => 0); Ada.Text_IO.New_Line; end Limiti_Float; Ecco loutput che si ottiene eseguendo il programma con GNAT 3.13p su Windows 2000: Il piu piccolo SHORT_FLOAT e: -3.40282E+38 Il piu grande SHORT_FLOAT e: 3.40282E+38 Cifre significative di SHORT_FLOAT: 6 Bit occupati da uno SHORT_FLOAT: 32 Il piu piccolo FLOAT e: -3.40282E+38 Il piu grande FLOAT e: 3.40282E+38 Cifre significative di FLOAT: 6 Bit occupati da un FLOAT: 32 Il piu piccolo LONG_FLOAT e: -1.79769313486232E+308 Il piu grande LONG_FLOAT e: 1.79769313486232E+308 Cifre significative di LONG_FLOAT: 15 Bit occupati da un LONG_FLOAT: 64 Il piu piccolo LONG_LONG_FLOAT e: -1.18973149535723177E+4932 Il piu grande LONG_LONG_FLOAT e: 1.18973149535723177E+4932 Cifre significative di LONG_LONG_FLOAT: 18 Bit occupati da un LONG_LONG_FLOAT: 96

27

Siccome il numero di cifre signicative dei tipi reali dipende dalla macchina e/o dal compilatore, preferibile denire dei propri tipi reali. La sintassi per fare ci la seguente: Liceo cantonale di Mendrisio, 2002 Claudio Marsan

28

CAPITOLO 1. INTRODUZIONE AL LINGUAGGIO ADA 95 type Nome_Tipo is digits numero;

dove Nome_Tipo il nome del tipo e numero il numero di cifre decimali che seguono il punto decimale. Esempio 1.3.15 Mediante ... type TEMPO is digits 4; type DISTANZA_ATOMICA is digits 15; ... si deniscono: il tipo TEMPO con 4 cifre decimali dopo il il punto decimale e destinato ad oggetti che rappresentano misurazioni del tempo; il tipo DISTANZA_ATOMICA con 15 cifre decimali dopo il punto decimale e destinato ad oggetti che rappresentano misurazioni di distanze atomiche. anche possibile limitare lintervallo dei numeri in virgola mobile che vogliamo denire. La sintassi la seguente: type Nome_Tipo is digits numero range minimo..massimo; Esempio 1.3.16 Le seguenti sono denizioni di tipi reali deniti su un intervallo limitato: ... type PERCENTUALE is digits 4 range 0.0 .. 100.0; type PROB is digits 6 range 0.0 .. 1.0; ... conveniente limitare i domini dei tipi reali poich, in caso di superamento dei limiti ssati, il compilatore reclama: questo aiuta a scrivere programmi pi adabili e permette di trovare pi facilmente alcuni tipi di errore. Con i numeri in virgola mobile si possono eseguire le comuni operazioni aritmetiche di somma, sottrazione, moltiplicazione, divisione (gli operandi devono essere sempre dello stesso tipo). Alcune osservazioni a proposito: la divisione tra numeri in virgola mobile restituisce un numero in virgola mobile; per il calcolo delle potenze si usa loperatore ** e lesponente deve necessariamente essere un intero; la priorit dellesecuzione delle operazioni quella dellalgebra; la priorit modicabile usando le parentesi (sono ammesse solo parentesi tonde!); nel package Ada.Numerics sono denite le costanti Pi per ed e per il numero di Eulero e; nel package Ada.Numerics.Elementary_Functions sono denite le pi comuni funzioni matematiche (funzioni trigonometriche, ciclometriche, logaritmiche, esponenziali, . . . ). Osservazione 1.3.10 Tipi diversi di numeri in virgola mobile non sono compatibili tra loro ne tantomeno lo sono con i tipi interi! Bisogna, per esempio, distinguere 100.0 da 100. Sono tuttavia permesse delle conversioni esplicite, come nellesempio seguente: ... x, y : FLOAT; ... x := y + 100; x := y + FLOAT(100); ...

-- sbagliato! -- corretto

Pi avanti vedremo altri tipi di numeri reali. Claudio Marsan Liceo cantonale di Mendrisio, 2002

1.3. PRIMI PASSI CON ADA 95

29

1.3.11

I tipi enumerativi

Molti fenomeni del mondo reale sono deniti da parole piuttosto che da numeri, per esempio i giorni della settimana, i mesi dellanno, i colori, i semi delle carte da gioco, . . . . Per rappresentare fenomeni come quelli elencati in un programma i numeri non sono sucienti: in Ada c la possibilit di utilizzare i tipi enumerativi che consentono di elencare tutti i possibili valori che il tipo pu assumere. Esempio 1.3.17 Il tipo GIORNO adatto alla rappresentazione dei giorni della settimana: type GIORNO is (LUNEDI, MARTEDI, MERCOLEDI, GIOVEDI, VENERDI, SABATO, DOMENICA); In seguito potremo dichiarare delle variabili di tipo GIORNO: oggi, domani : GIORNO; e usarle in un programma: ... oggi := VENERDI; domani := SABATO; ... Esempio 1.3.18 Il tipo COLORE adatto alla rappresentazione dei colori principali nel sistema RGB (red, green, blue): type COLORE is (ROSSO, VERDE, BLU); In un programma potremmo poi avere: ... colore_auto : COLORE; ... begin ... colore_auto := BLU; ... Esempio 1.3.19 Il tipo SEME adatto alla rappresentazione dei semi delle carte da gioco francesi: type SEME is (QUADRI, CUORI, FIORI, PICCHE); In un programma potremmo poi avere: ... seme_giocato : SEME; ... begin ... seme_giocato := PICCHE; ... Osservazione 1.3.11 Si possono anche inizializzare, in fase di dichiarazione, variabili di tipo enumerativo, per esempio: ieri : GIORNO := GIOVEDI; Liceo cantonale di Mendrisio, 2002 Claudio Marsan

30

CAPITOLO 1. INTRODUZIONE AL LINGUAGGIO ADA 95

La sintassi generale per la denizione di un tipo enumerativo la seguente: type Nome_Tipo is (val1, val2, ..., valN); Allinterno del tipo i valori, che sono costanti, sono ordinati nel modo seguente: val1 < val2 < ... < valN

Esempio 1.3.20 Riferendosi agli esempi precedenti avremo: MARTEDI < MERCOLEDI QUADRI < PICCHE ROSSO < BLU Siccome i tipi enumerativi sono ordinati si possono usare gli attributi SUCC(val) (restituisce il valore che, nella denizione del tipo, segue val) e PRED(val) (restituisce il valore che, nella denizione del tipo, precede val). Esempio 1.3.21 Il seguente frammento di programma riferito agli esempi precedenti: ... domani := GIORNOPRED(SABATO); -- VENERDI seme_giocato := SEMESUCC(QUADRI); -- CUORI colore_auto := COLORESUCC(BLU); -- errore! ... Da notare che gli attributi SUCC e PRED sono utilizzabili anche per i tipi interi (in Ada95 anche per i tipi in virgola mobile). Anch si possano utilizzare le procedure di input e output con i tipi enumerativi bisogna inserire allinterno della procedura una riga simile alla seguente (il signicato sar spiegato molto pi avanti, per il momento usiamola e basta!) package nome_del_package is new Ada.Text_IO.Enumeration_IO(nome_del_tipo); Sopra nome_del_package scelto dal programmatore e nome_del_tipo il nome del tipo enumerativo per il quale si desidera avere a disposizione le procedure di input e output. Esempio 1.3.22 Consideriamo il programma seguente: -----Nome del file: CARTE.ADB Autore: Claudio Marsan Data dellultima modifica: 30 gennaio 2002 Scopo: input/output di una variabile di tipo enumerativo Testato con: Gnat 3.13p su Windows 2000

with Ada.Text_IO; procedure Carte is type SEME is (QUADRI, CUORI, FIORI, PICCHE); package Seme_IO is new Ada.Text_IO.Enumeration_IO(SEME); seme_giocato : SEME; Claudio Marsan Liceo cantonale di Mendrisio, 2002

1.3. PRIMI PASSI CON ADA 95

31

begin Ada.Text_IO.New_Line; Ada.Text_IO.Put(Item => "Dare un seme: "); Seme_IO.Get(Item => seme_giocato); seme_giocato := SEMEPRED(seme_giocato); Seme_IO.Put(Item => seme_giocato); end Carte; Segue un esempio di output del programma: Dare un seme: FIORI CUORI Esempio 1.3.23 Consideriamo il programma seguente: -----Nome del file: GIORNI.ADB Autore: Claudio Marsan Data dellultima modifica: 30 gennaio 2002 Scopo: input/output di variabili di tipo enumerativo Testato con: Gnat 3.13p su Windows 2000

with Ada.Text_IO; procedure Giorni is type GIORNO is (LUNEDI, MARTEDI, MERCOLEDI, GIOVEDI, VENERDI, SABATO, DOMENICA); package Giorno_IO is new Ada.Text_IO.Enumeration_IO(GIORNO); ieri, oggi, domani : GIORNO; begin Ada.Text_IO.New_Line; Ada.Text_IO.Put(Item => "Che giorno e oggi? "); Giorno_IO.Get(Item => oggi); ieri := GIORNOPRED(oggi); Ada.Text_IO.Put(Item => "Ieri era "); Giorno_IO.Put(Item => ieri); Ada.Text_IO.New_Line; domani := GIORNOSUCC(oggi); Ada.Text_IO.Put(Item => "Domani sara "); Giorno_IO.Put(Item => domani); Ada.Text_IO.New_Line; end Giorni; -- Il programma genera un errore se la variabile "oggi" assume il valore -- "LUNEDI" oppure "DOMENICA" (si rimedia facilmente con le istruzioni -- condizionali che vedremo in seguito). Segue un esempio di output del programma: Liceo cantonale di Mendrisio, 2002 Claudio Marsan

32

CAPITOLO 1. INTRODUZIONE AL LINGUAGGIO ADA 95

Che giorno e oggi? giovedi Ieri era MERCOLEDI Domani sara VENERDI Per i giorni di inizio e ne settimana ci sono dei problemi che potranno essere risolti appena avremo studiato listruzione if ... then .... Vediamo comunque il messaggio derrore fornito dal compilatore GNAT 3.12p:

Che giorno e oggi? domenica Ieri era SABATO raised CONSTRAINT_ERROR : giorni.adb:29

Il tipo BOOLEAN un tipo enumerativo predenito che permette di utilizzare variabili che possono assumere solo i valori FALSE (falso) o TRUE (vero). Esso verr trattato pi avanti, quando studieremo le istruzioni condizionali. La sua denizione : type BOOLEAN is (FALSE, TRUE); Anche il tipo CHARACTER un tipo enumerativo predenito. Per memorizzare un carattere sono necessari 8 bit e dunque i possibili valori di una variabile di tipo CHARACTER sono 256 (in parte sono caratteri di controllo, in parte caratteri stampabili quali lettere accentate o con la dieresi). I primi 128 sono quelli del codice ASCII (i caratteri sono numerati da 0 a 127): type CHARACTER is (nul, soh, ..., a, ..., ~, del); Linsieme dei caratteri stampabili con Ada 95 denito nella norma ISO 8859 e si chiama LATIN_1. Il package Ada.Characters.Latin_1 contiene i nomi simbolici per i caratteri non stampabili. Per poter trattare anche linguaggi che non sono basati sullalfabeto latino, Ada 95 ha un altro tipo standard enumerativo, chiamato WIDE_CHARACTER. Questo tipo fa uso di 16 bit, cosa che permette di rappresentare ben 65536 caratteri diversi (essi sono specicati nello standard ISO 10646 BMP). Come gi visto linput e loutput di variabili di tipo CHARACTER possibile grazie alle procedure presenti nel package Ada.Text_IO; per variabili di tipo WIDE_CHARACTER occorrer invece il package Ada.Wide_Text_IO.

1.3.12

Alcuni attributi utili

Per il tipo CHARACTER (e WIDE_CHARACTER) ci sono due attributi interessanti: se ch una variabile di tipo CHARACTER allora con CHARACTERPOS(ch) si ottiene il codice ASCII del carattere ch; se N un intero allora con CHARACTERVAL(N) si ottiene il carattere avente il codice ASCII N. Esempio 1.3.24 CHARACTERPOS(a) restituir 97; CHARACTERVAL(97) restituir a. Gli attributi VALUE e IMAGE sono utilizzabili con i tipi discreti (interi ed enumerativi): TVALUE(s): trasforma la stringa s in un valore del tipo discreto T (se un simile valore non fa parte di T il compilatore genera un errore); TIMAGE(v): trasforma il valore v del tipo discreto T in una stringa. Esempio 1.3.25 Grazie agli attributi VALUE e IMAGE possiamo riscrivere il programma dellesempio 1.3.22 nel modo seguente, evitando di denire il package Semi_IO (nota: i numeri di riga non devono essere digitati): Claudio Marsan Liceo cantonale di Mendrisio, 2002

1.3. PRIMI PASSI CON ADA 95 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 ------Nome del file: CARTE2.ADB Autore: Claudio Marsan Data dellultima modifica: Scopo: input/output di una usando gli attributi VALUE Testato con: Gnat 3.13p su

33

30 gennaio 2002 variabile di tipo enumerativo e IMAGE Windows 2000

with Ada.Text_IO; procedure Carte2 is type SEME is (QUADRI, CUORI, FIORI, PICCHE); seme_giocato : SEME; s : STRING(1..6); lung : NATURAL; begin Ada.Text_IO.New_Line; Ada.Text_IO.Put(Item => "Dare un seme: "); Ada.Text_IO.Get_Line(Item => s, Last => lung); seme_giocato := SEMEVALUE(s(1..lung)); seme_giocato := SEMEPRED(seme_giocato); Ada.Text_IO.Put(Item => SEMEIMAGE(seme_giocato)); end Carte2;

Il programma necessita di qualche spiegazione: nella riga 15 si denisce la variabile s come una stringa di (al massimo) sei caratteri, sucienti per memorizzare i valori del tipo enumerativo SEME; nella riga 16 si denisce la variabile lung: in essa verr memorizzato il numero di caratteri digitato dallutente; nella riga 21 si legge la stringa s e si memorizza la sua lunghezza in lung; nella riga 22 il compito di SEMEVALUE quello di trasformare la stringa s (o meglio: i suoi primi lung caratteri) nel corrispondente valore del tipo SEME; nella riga 24 il compito di SEMEIMAGE quello di convertire il valore di seme_giocato in una stringa, cos da poterla visualizzare. Possiamo usare gli attributi VALUE e IMAGE anche con gli altri tipi di dati discreti, come per esempio gli interi da noi deniti. In Ada 95 luso di tali attributi permesso anche con i numeri in virgoli mobile. Esempio 1.3.26 Il programma seguente mostra luso di IMAGE con un tipo di dati in virgola mobile denito dal programmatore: -----Nome del file: MY_FLOAT.ADB Autore: Claudio Marsan Data dellultima modifica: 30 gennaio 2002 Scopo: uso di IMAGE Testato con: Gnat 3.13p su Windows 2000

with Ada.Text_IO; Liceo cantonale di Mendrisio, 2002 Claudio Marsan

34

CAPITOLO 1. INTRODUZIONE AL LINGUAGGIO ADA 95

procedure My_Float is type REAL is digits 10; PI : REAL := 3.141592654; begin Ada.Text_IO.New_Line; Ada.Text_IO.Put(Item => "Pi greco vale circa: "); Ada.Text_IO.Put(Item => REALIMAGE(PI)); Ada.Text_IO.New_Line; end My_Float;

Esempio 1.3.27 Il seguente programma permette di leggere un numero di qualsiasi tipo e di memorizzarlo in una variabile di tipo FLOAT: ------Nome del file: LEGGI_NUMERO.ADB Autore: Claudio Marsan Data dellultima modifica: 30 gennaio 2002 Scopo: legge un numero reale come stringa e lo memorizza poi in una variabile reale Testato con: Gnat 3.13p su Windows 2000

with Ada.Text_IO, Ada.Float_Text_IO; procedure Leggi_Numero is s : STRING(1..30); lung : NATURAL; x : FLOAT; begin Ada.Text_IO.New_Line(Spacing => 2); Ada.Text_IO.Put(Item => "Dai un numero reale x: "); Ada.Text_IO.Get_Line(Item => s, Last => lung); x := FLOATVALUE(s(1..lung)); Ada.Text_IO.New_Line; Ada.Text_IO.Put(Item => "x vale: "); Ada.Float_Text_IO.Put(Item => x); end Leggi_Numero; Nel caso volessimo denire linsieme dei numeri in virgola mobile positivi dovremmo conoscere qual il pi piccolo FLOAT maggiore di 0. Questo valore si ottiene usando lattributo SMALL: per esempio FLOATSMALL ritorna il pi piccolo FLOAT positivo. Potremo cos denire i FLOAT positivi nel modo seguente: type POSITIVE_FLOAT is digits 6 range FLOATSMALL..FLOATLAST; Vedremo in seguito altri attributi utili. Claudio Marsan Liceo cantonale di Mendrisio, 2002

1.4. ISTRUZIONI CONDIZIONALI

35

1.3.13

Flusso di controllo

I programmi che abbiamo visto nora hanno tutti la caratteristica di essere eseguiti in modo sequenziale, ossia il computer inizia ad eseguire la prima istruzione del programma, poi la seguente, poi la seguente, . . . no a che lultima istruzione che appare nel programma stata eseguita. Ma i computer possono fare di pi: possono eseguire unazione ripetutamente e decidere che alternativa prendere tra quelle proposte ad un certo punto del programma. Ci possibile tramite le strutture di controllo che governano il usso di controllo nellesecuzione di un programma. Si distinguono: esecuzione sequenziale: quella che abbiamo gi visto; esecuzione selettiva: ad essa sono associate le istruzioni condizionali ; esecuzione ripetitiva: ad essa sono associati i cicli. Nei prossimi paragra ci occuperemo di apprendere le istruzioni necessarie per modicare il usso di un programma.

1.4

Istruzioni condizionali

I linguaggi di programmazione solitamente permettono al programmatore di far decidere al computer se unistruzione o una sequenza di istruzioni deve essere eseguita oppure decidere quale fra due possibili sequenze di istruzioni deve essere eseguita. In Ada ci si pu fare essenzialmente con le istruzioni condizionali introdotte dalla parola riservata if.

1.4.1

Listruzione if ...

then ...

end if;

La forma pi semplice la seguente: if condizione then istruzione_1; istruzione_2; ... istruzione_N; end if; dove condizione unespressione booleana, ossia unespressione che pu assumere solo il valore vero (TRUE) o falso (FALSE). Esempio 1.4.1 Consideriamo il seguente frammento di programma: ... n : INTEGER; ... begin ... if n > 1_000_000 then Ada.Text_IO.Put(Item => "Piu di un milione"); end if; ... Se la variabile n assumer un valore maggiore di 1 000 000 (ossia se la condizione n > 1_000_000 TRUE) sullo schermo verr scritta la stringa Piu di un milione; in caso contrario il programma continua con la prima istruzione dopo end if;. Esempio 1.4.2 Consideriamo il seguente frammento di programma: Liceo cantonale di Mendrisio, 2002 Claudio Marsan

36

CAPITOLO 1. INTRODUZIONE AL LINGUAGGIO ADA 95 ... n, m : INTEGER; ... begin ... m := n mod 2; if m = 0 then Ada.Integer.Text_IO.Put(Item => n); Ada.Text_IO.Put(Item => " e pari"); end if; ...

Se m sar uguale a 0 verranno eseguite le due istruzioni dopo la parola riservata then, in caso contrario il programma continua con la prima istruzione dopo end if;. Esempio 1.4.3 Nel prossimo frammento di programma si memorizza nella variabile massimo il pi grande fra i numeri in virgola mobile x e y: ... x, y, massimo : FLOAT; ... begin ... if x > y then massimo := x; end if; if x y then massimo := x; else massimo := y; end if; ... Esempio 1.4.5 Miglioriamo il codice dellesempio 1.4.2: ... n, m : INTEGER; ... begin ... m := n mod 2; if m = 0 then Ada.Integer.Text_IO.Put(Item Ada.Text_IO.Put(Item => " e else Ada.Integer.Text_IO.Put(Item Ada.Text_IO.Put(Item => " e end if; ...

=> n); pari"); => n); dispari");

Osservazione 1.4.1 Come si pu notare dagli