Programmazione Tutto per la gloria di Dio. 1 Introduzione Un programma `e un piano di azione che deve essere eseguito da un esecutore, di solito uno strumento automatico, la maggior parte delle volte un computer. Un programma consiste in un insieme finito di comandi, o istruzioni, ognuno dei quali f`a eseguire all’esecutore una particolare operazione elementare sui dati, che sono memorizzati nella memoria dell’esecutore e i cui nomi sono i parametri dei comandi. Si ottiene l’automatismo dell’esecutore dal fatto che ogni comando corrente, eccetto il comando stop, punta unicamente ad un comando del programma che deve essere eseguito dopo quello corrente. Una caratteristica particolare dell’esecutore `e la presenza di comandi ramificati (transizioni condizionali) nei quali la scelta di una tra pi` u azioni indicate viene fatta sulla base di propriet`a da verificare dei dati menzionati nel comando. Da ci`o ne consegue che quando si usa un programma, la successione dei comandi pu`o variare, dopo aver definito in maniera unica i dati. Perci`o un programma, sebbene sia un oggetto finito, permette all’utente di lavorare su una variet`a di dati potenzialmente infinita. I programmi sono importanti non solo come prescrizioni per computers, ma anche come sorgenti di conoscenza operazionale degli uomini. 1 2 2 Uno sguardo all’interno Abbiamo detto che un programma `e una successione finita di istruzioni che agiscono su dati in memoria. Per arginare la complessit`a di un programma, `e utile isolare sottosuccessioni di istruzioni, dette procedure, che si ripetono e che eseguono specifiche azioni, e raggruppare tali procedure in differenti moduli, detti unit` a. Il tutto in un’ottica di dividere sistematicamente il problema in parti strutturate, per agevolarne la comprensione, la produzione, la gestione, la costante rielaborazione, il riutilizzo, la semplificazione, la lettura. Per una buona gestione della memorizzazione e dell’elaborazione dei dati, questi ultimi vengono divisi in tipi. Elementi di uno stesso tipo occupano indicativamente identici spazi di memoria, e su di essi agiscono identiche operazioni. Tra i vari tipi di dati, si possono riconoscere, oltre a quelli semplici (numeri interi, numeri reali, caratteri, stringhe di testo, vero o falso, ecc.), gli array, ovvero tipi composti da un numero fissato di dati semplici di uno stesso tipo (coppie di numeri reali, matrici 3x3 di numeri interi, ecc.) e i record, cio`e tipi strutturati mediante un numero fissato di dati di vario tipo (una coppia di un numero intero e una stringa). All’interno di uno stesso tipo possiamo isolare quei dati che rimangono invariati, le costanti, e quei dati che possono cambiare, le variabili. 3 3 Linguaggi di programmazione Lo scopo di base di un linguaggio di programmazione `e quello di programmare, cio`e formulare programmi che possono essere eseguiti su un computer. Come nei linguaggi naturali, un linguaggio di programmazione `e costruito su un alfabeto di simboli di base (con i quali viene scritto il programma) nella forma di un sistema gerarchico di elementi grammaticali, tra i quali vengono date delle relazioni (in maniera simile alle parole, frasi e affermazioni, le cui connessioni sono date dalle regole sintattiche). Esistono numerosi linguaggi di programmazione, tra cui `e doveroso ricordare il C, Java, il Fortran e il Prolog. Affronteremo qui il linguaggio Pascal. La ragione di tale scelta `e eminentemente didattica. 4 4 Tipi semplici nel Pascal Il Pascal permette l’utilizzo di un certo numero di tipi di dati di base. Qui di seguito accenneremo ai tipi principali di dati che incontreremo nella pratica, insieme alle operazioni e alle relazioni su di essi che il Pascal fornisce. 4.1 Tipo boolean I dati di tipo boolean sono i valori Vero e Falso. Il Pascal fornisce come operazioni sui booleani i connettivi logici ¬, ∧, ∨, e le relazioni =, 6=, <, >, 6, >. Esempio. Si ha che ¬ Vero=Falso 4.2 Falso ∧ Vero = Falso (Falso < Vero) = Vero Tipo char I dati di tipo char sono i caratteri ASCII. Ricordando che ogni carattere ASCII ha associato un corrispondente numero naturale (il suo codice), il Pascal fornisce due funzioni, Chr e Ord, la prima delle quali associa ad un numero naturale il suo carattere corrispondente, mentre la seconda associa ad ogni carattere il suo codice. Esempio. Chr(63)=? Chr(97)=a Ord(0)=48 Ord(+)=43 5 4.3 Tipo integer I dati di tipo integer sono gli interi tra −32768 e 32767. Il Pascal fornisce come operazioni sugli interi +, −, ·, la divisione intera div e la funzione resto mod. Il Pascal fornisce sugli interi le relazioni =, 6=, <, >, 6, >. Esempio. Valgono le seguenti 7 div 3 = 2 8 div 8 = 1 7 mod 3 = 1 8 mod 8 = 0 4.4 6 div 9 = 0 6 mod 9 = 6 Tipo real I dati di tipo real corrispondono ad alcuni numeri reali. Il Pascal fornisce come operazioni sui reali, tra le altre, +, −, ·, /, il valore assoluto abs, la parte intera int, l’arrotondamento round, il quadrato sqr, la radice quadrata sqrt, il troncamento trunc. Il Pascal fornisce sui reali le relazioni =, 6=, <, >, 6, >. 4.5 Tipo string I dati di tipo string sono stringhe, cio`e sequenze, di al massimo 255 caratteri ASCII. Il Pascal fornisce come operazioni sulle stringhe, tra le altre, il +, che permette di concatenare due stringhe, troncando ovviamente il risultato se affiancate eccedono i 255 caratteri, e la funzione length che rende il numero di caratteri di una stringa. Il Pascal fornisce sulle stringhe le relazioni =, 6=, <, >, 6, >. Esempio. pelli + cani = pellicani 6 5 Alfabeto del Pascal Nel Pascal, l’alfabeto dei simboli di base consiste nelle dieci cifre decimali 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, nelle lettere dell’alfabeto inglese (il Pascal non f`a differenza tra maiuscole e minuscole) a, n, b, o, c, p, d, q, e, r, f, s, g, t, h, u, i, v, j, w, i simboli di parentesi ( , ) , [ , ] , { , } i simboli di punteggiatura , ; : . alcuni simboli di operazioni e relazioni logiche e aritmetiche + , - , * , / , = , < , > altri simboli, come ad esempio ˆ , $ , @ , ’ , k, x, l, y, m, z, 7 6 Unit` a lessicali in Pascal In ogni linguaggio di programmazione, gli elementi al livello pi` u basso, formati da catene di simboli di base, sono chiamati lessemi o unit` a lessicali. Ogni lessema appartiene ad una determinata classe. Nel Pascal, le principali classi sono gli interi, i reali, le stringhe, gli operatori, gli identificatori e le parole riservate. 6.1 Lessemi di tipo boolean Le unit`a lessicali di tipo boolean corrispondono ai valori Vero e Falso. Gli unici lessemi di questo tipo sono true e false. 6.2 Lessemi di tipo char Questi lessemi corrispondono ai caratteri ASCII. In Pascal, • sono caratteri ASCII racchiusi da apostrofi, • il singolo carattere apostrofo `e scritto come due apostrofi tra apostrofi. Esempio. I seguenti sono lessemi di tipo char in Pascal ’c’ 6.3 ’’’’ ’2’ ’?’ Lessemi di tipo integer Le unit`a lessicali di tipo integer corrispondono ai numeri interi. Sono catene di cifre decimali, precedute o meno da uno tra i simboli + e −. Viene richiesto che, come numeri, siano compresi tra −32768 e 32767. Esempio. I seguenti sono interi in Pascal 0 71 -23 +107 mentre i seguenti non sono interi in Pascal +-3 100000. 8 6.4 Lessemi di tipo real I lessemi di tipo real corrispondono ai numeri reali. Sono in virgola mobile, moltiplicati per una potenza intera di 10. Sono del tipo I.DeL oppure I.DEL dove I `e un numero intero, D `e un numero naturale ed L `e un numero intero. e, od E, equivale a 10ˆ. D pu`o non essere presente, nel qual caso la virgola si pu`o omettere. La parte eL, o EL, si pu`o omettere. Viene richiesto che, come numeri positivi, siano compresi in valore assoluto tra 2.9 · 10−39 e 1.7 · 1038 . Esempio. I seguenti sono reali in Pascal 0 1e3 -2.3E+10 0.1e-7 mentre i seguenti non sono reali in Pascal e3 6.5 2e100. Lessemi di tipo string In Pascal, le stringhe, rappresentanti testi, • sono catene di al massimo 255 caratteri racchiuse da apostrofi, • una stringa con niente tra gli apostrofi `e la stringa nulla, • due apostrofi di seguito in una stringa denotano un singolo carattere, l’ apostrofo. Esempio. I seguenti sono lessemi di tipo string in Pascal ’ciao’ ’’ ’w2+’ ’l’’Algebra’ ’Il male ` e di chi lo f` a’ 9 6.6 Operatori In Pascal, gli operatori corrispondono a funzioni su dati. Avremo 6.6.1 Operatori booleani Assumono valori booleani e il risultato `e di tipo booleano: not (¬) 6.6.2 and (∧) or (∨) Operatori interi Assumono valori intero e il risultato `e di tipo intero: + * (·) - 6.6.3 div mod sqr (2 ) Operatori reali Assumono valori reali e il risultato `e di tipo intero o reale: 6.6.4 + - * / abs arctan cos exp frac int ln pi sin sqr sqrt Operatori su stringhe Assumono valori stringhe e il risultato `e una stringa o di tipo intero: + length pos 10 6.6.5 Operatori relazionali Assumono valori di ogni tipo semplice e il risultato `e di tipo booleano: <> (6=) = 6.7 < <= (6) > >= (>) Identificatori In ogni linguaggio di programmazione, gli identificatori denotano i vari oggetti (cio`e i loro nomi) del programma che sono definiti nel programma stesso. Principalmente, tali oggetti sono campi nei records, costanti, funzioni, procedure, programmi, tipi, unit`a, variabili. In Pascal, • gli identificatori sono catene di caratteri di qualsiasi lunghezza, ma solo i primi 63 caratteri sono significativi, • il primo carattere deve essere una lettera, • i successivi caratteri possono essere lettere, cifre decimali, o il simbolo . Esempio. I seguenti sono identificatori in Pascal x a1 yy punto medio delta I seguenti non sono identificatori in Pascal 2x x y 6.8 Parole riservate po’ lealt` a a@b In ogni linguaggio di programmazione, alcuni identificatori sono definiti dal linguaggio stesso. Tali identificatori prendono il nome di parole riservate. Nel Pascal, le principali parole riservate sono: 11 and array begin case const div do downto else end for function if mod not of or procedure program repeat then to until uses var while 12 7 Strutture di base in Pascal I livelli successivi di elementi di un linguaggio di programmazione. Sono essenzialmente di tre tipi: espressioni, dichiarazioni, istruzioni. 7.1 Espressioni Le espressioni sono sorgenti di valori, ottenute a partire da operatori e operandi. Gli operandi sono principalmente costanti, variabili e chiamate di funzioni, eventualmente usando le parentesi tonde. Esempio. Espressioni intere: n+1 (2*y) mod 3 lenght(x)-int(3.2) Espressioni booleane: i < 3 7.2 ord(’x’) <= ord(’y’) sqr(b) = 4*a*c Dichiarazioni Le dichiarazioni sono sorgenti di informazione assegnate all’occorrenza che definisce il lessema. Essenzialmente, decrivono la tipologia di valori calcolati dall’esecuzione del programma, la loro rappresentazione e il modo in cui vengono immagazzinati nella memoria del computer. Per valori composti come gli array (vettori, matrici) e valori strutturati (record) viene specificato anche il modo di accedere ai suoi componenti elementari. 13 7.2.1 Dichiarazioni di costanti Una dichiarazione di costante definisce un identificatore come una costante di un determinato tipo. La sintassi `e: const identificatore = espressione ; identificatore = espressione ; ... Esempio. const base = 10 ; e = 2.71828 ; 7.2.2 Dichiarazioni di variabili Una dichiarazione di variabile definisce un identificatore come una variabile di un determinato tipo. La sintassi `e: var identificatore : tipo ; identificatore , identificatore : ... Esempio. var n , m : integer ; x , y , z : real ; nome : string ; tipo ; 14 7.3 Istruzioni Le istruzioni, o affermazioni, sono unit`a di operazioni finite nel programma; le istruzioni di base sono principalmente gli assegnamenti, le chiamate di procedure, le istruzioni begin...end, le istruzioni condizionali, le istruzioni iterative e le istruzioni ricorsive. 7.3.1 Assegnamenti Un assegnamento attribuisce il valore di un’espressione ad una variabile. La sintassi `e: identificatore := espressione ; Esempio. area := b*h ; i := i+1 ; alfa := beta and gamma ; 7.3.2 Chiamate di procedure La definizione di una procedura introduce una notazione abbreviata e parametrizzata per la funzione di una certa parte del programma (il corpo della procedura). L’esecuzione del corpo della procedura pu`o essere conseguentemente trattata come un’operazione elementare causata da una chiamata della procedura. Il Pascal fornisce alcune procedure. Qui mi preme considerare il write e il read (per le altre, `e sufficiente accedere all’ottimo help del Turbo Pascal). La procedura write scrive sul monitor le espressioni Oi di tipo semplice. La procedura writeln, inoltre, porta il cursore all’inizio della riga successiva. Le sintassi: write(O1) ; write(O1,O2) ; ... 15 La procedura read legge da tastiera uno o pi` u valori e li associa alle variabili Vi. La procedura readln, inoltre, salta alla linea successiva. Le sintassi: read(V1) ; read(V1,V2) ; ... 7.3.3 Istruzioni begin ... end ` un’istruzione composta. In questo modo, tutte le istruzioni comprese E tra le parole riservate begin ed end (da intendersi come semplici parentesi), vengono trattate come un’unica istruzione. La sintassi `e: begin istruzione ; istruzione ; ... istruzione end ; 7.3.4 Istruzioni condizionali In un’istruzione condizionale, la scelta tra una o pi` u istruzioni dipende dal verificarsi o meno di una condizione (espressione booleana). In Pascal, abbiamo le istruzioni if e case: Per la prima, la sintassi `e: if espressione then istruzione ; oppure if espressione then istruzione else istruzione ; 16 Se la condizione dopo l’if `e verificata, viene eseguita l’istruzione dopo il then, altrimenti, nel secondo caso, viene eseguita l’istruzione dopo l’else. Esempio. if abs(n) < 10 then writeln(n,’ ha un’’unica cifra’) else writeln(n,’ ha almeno due cifre’); Per la seconda, la sintassi `e: case espressione of case : istruzione ; ... case : istruzione ; end ; oppure case espressione of case : istruzione ; ... case : istruzione ; else istruzione end ; In questa istruzione, il valore dell’espressione seleziona l’istruzione corrispondente. Esempio. case n mod 2 of ` pari’) ; 0 : writeln(n,’ e 1 : writeln(n,’ ` e dispari’) ; end ; 7.3.5 Istruzioni iterative Un’istruzione iterativa ripete un numero fissato di volte (itera) una certa parte del programma (il corpo dell’iterazione). In Pascal, abbiamo l’istruzione for, la cui sintassi `e: 17 for var := primo to ultimo do istruzione ; oppure for var := primo downto ultimo do istruzione ; Esempio. for i:=1 to 10 do writeln(i*i) ; 7.3.6 Istruzioni ricorsive Un’istruzione ricorsiva dispone un’esecuzione ripetitiva di una certa parte del programma (il corpo della ricorsione), dove il numero delle ripetizioni `e determinato da una data condizione. In Pascal, abbiamo le istruzioni while e repeat: Per la prima, la sintassi `e: while espressione do istruzione ; L’istruzione dopo il do viene ripetuta fintanto che l’espressione rimane vera. Si noti che se l’espressione `e inizialmente falsa, l’istruzione non viene eseguita. Esempio. i:=2 ; while (n mod i) <> 0 do i:=i+1 ; if i = n then writeln(n,’ ` e primo’) else writeln(n,’ ` e composto’); Per la seconda, la sintassi `e: repeat istruzione ; istruzione ; ... istruzione until espressione ; 18 Le istruzioni comprese tra il repeat e l’until vengono eseguite fintanto che l’espressione risulta falsa. Quando l’espressione diventa vera, si esce dal ciclo. Si noti che tali istruzioni vengono eseguite almeno una volta. Esempio. : repeat readln(s) until (s=’m’) or (s=’f’) ; 19 8 Struttura di un programma Un programma in Turbo Pascal pu`o avere il seguente aspetto program identificatore ; uses ... ; const ... ; type ... ; var ... ; procedure ... ; function ... ; begin istruzione ; ... end. Esempio. Ecco il vostro primo programma: program pippo ; begin writeln(’Ciao mondo!’) end. La clausola uses nomina le unit`a (librerie) utilizzate dal programma. la clausola type permette di definire nuovi tipi. Le clausole procedure e function permettono di definire nuove funzioni e procedure. Esempio. Le seguenti producono la stessa funzione potenza: function potenza(x , n : integer): integer; begin if n=0 then potenza:= 1 else potenza:= x ∗ potenza(x,n-1) end 20 function potenza(x , n : integer): integer; var i, p: integer; begin p:= 1 ; for i:= 1 to n do p:= p ∗ x ; potenza:= p end
© Copyright 2025 ExpyDoc