Funzioni e procedure

Dimensione: px
Iniziare la visualizzazioe della pagina:

Download "Funzioni e procedure"

Transcript

1 Funzioni e procedure DOTT. ING. LEONARDO RIGUTINI DIPARTIMENTO INGEGNERIA DELL INFORMAZIONE UNIVERSITÀ DI SIENA VIA ROMA SIENA UFF

2 Sottoprogrammi

3 Sottoprogrammi Nella creazione di un programma può accadere che problemi simili appaiano in varie parti diverse La soluzione più ovvia è quella di replicare il codice in ogni parte dove è necessario, ma questa soluzione non è certamente la più comoda ed efficace: - Se il codice ha un errore, infatti, esso sarà replicato in tutte le parti in cui quel codice è stato copiato - Se quella parte di codice viene aggiornata, sarà necessario aggiornare tutte le parti in cui è stato copiato Molto poco flessibile e manutenibile: - uso di sottoprogrammi

4 Sottoprogrammi Sottoprogrammi: parti di codice separate dal flusso principale del programma che possono essere richiamate laddove sia richiesta tale funzionalità senza dover replicare il codice ogni volta Un sottoprogramma deve essere innanzitutto definito, cioè deve essere dichiarato da qualche parte ciò che esso esegue, su cosa lo esegue e cosa restituisce (se restituisce qualcosa)

5 Sottoprogrammi Una volta definito, il sottoprogramma può e deve essere implementato Implementare: scrivere il corpo del sottoprogramma, dichiarando le variabili necessarie e scrivendo le istruzioni che permettono di eseguire il compito per cui è stato progettato Una volta dichiarato e implementato, si può far riferimento a tale sottoprogramma ogni volta che nel codice è richiesta la funzionalità implementata nel sottoprogramma

6 Struttura completa di un programma C

7 Struttura di un programma La struttura di un programma C deve includere: - Una parte di direttive - Un programma principale (il main) che a sua volta è costituito da una parte dichiarativa (dichiarazione variabili) ed una esecutiva (istruzioni) A questa struttura possiamo aggiungere nuovi elementi derivati dalla scomposizione del problema in sottoprogrammi: Una parte dichiarativa globale Una serie di definizioni di sottoprogrammi

8 Struttura di un programma In particolare: - Parte dichiarativa globale: questa parte è compresa tra la parte di direttive ed il programma principale (il main). Essa contiene la dichiarazione di tutti gli elementi che sono condivisi (ossia usati in comune) dal programma principale e dai sottoprogrammi. Tali elementi possono essere costanti, tipi, variabili ed altro ancora. Per esempio se nella parte dichiarativa troviamo la dichiarazione int x; ciò significa che alla variabile x possono avere accesso il programma principale e tutti i suoi sottoprogrammi. - Una serie di definizioni di sottoprogrammi: in questa parte sono dichiarate tutti i sottoprogrammi che poi sono implementati nel progetto.

9 Struttura di un programma La nuova struttura dei programmi appena costruita introduce una importante novità: diversi elementi (variabili, tipi ecc ) possono essere dichiarati in posti diversi Vedremo in effetti che anche i sottoprogrammi possono avere la propria parte dichiarativa. Ma allora: - Perché abbiamo bisogno di dichiarare diversi elementi in posti diversi? - Esistono delle regole che dicono quali elementi possono essere usati dai sottoprogrammi?

10 Struttura di un programma Le domande precedenti avranno risposta più avanti Per adesso limitiamoci a dire che: - Il programma principale e tutti i sottoprogrammi possono utilizzare tutti e soli gli elementi dichiarati nella propria parte dichiarativa, nonché quelli che sono stati dichiarati nella parte dichiarativa globale

11 Funzioni e procedure

12 Funzioni e procedure Ma cosa sono di preciso i sottoprogrammi? Ogni sottoprogramma è un blocco più o meno lungo di codice che riceve in ingresso alcuni parametri (anche nessuno) e può restituire un valore: I parametri di ingresso sono variabili in cui sono inseriti i valori nel momento in cui il sottoprogramma è utilizzato nelle varie parti del codice Il sottoprogramma utilizza questi parametri per eseguire il suo compito ed eventualmente restituisce a sua volta al chiamante un valore

13 Funzioni e procedure Formalmente esistono due tipologie di sottoprogrammi: - Le funzioni, che in analogia con le funzioni matematiche, ricevono alcuni valori in ingresso e restituiscono un valore in uscita - Le procedure, che ricevuti alcuni dati in ingresso, eseguono un compito che non può concettualmente essere associato ad una funzione (es. stampa, aggiornamento ecc ) La distinzione è formale ma utile dal punto di vista didattico: Le procedure, in effetti possono essere assimilate a funzioni che non restituiscono alcun valore, ma eseguono semplicemente un compito

14 Funzioni

15 Funzioni Dal punto di vista matematico, una funzione è una regola matematica che prende valori da un dominio e genera valori appartenenti ad un codominio: - Somme, funzioni aritmetiche, ecc In informatica una funzione è molto simile alla definizione matematica: una funzione utilizza alcune variabili ognuna di un certo tipo (=dominio) e resituisce un valore (=codominio)

16 Funzioni Per costruire ed usare come sottoprogrammi operazioni non già disponibili nel linguaggio sono necessari due passi: - La definizione della funzione - La chiamata della funzione

17 Dichiarazione di funzione Un sottoprogramma di tipo funzione viene chiamato brevemente funzione La dichiarazione di una funzione è costituita da: - Una testata (o header) - L implementazione racchiusa tra parentesi graffe e costituita a sua volta da: La parte dichiarativa (detta parte dichiarativa locale) La parte esecutiva (detta corpo della funzione)

18 Header La testa contiene le informazioni più rilevanti per il corretto utilizzo della funzione ed è costituita a sua volta da: - Tipo del risultato - Identificatore della funzione (nome della funzione) - Lista dei parametri, su cui la funzione è applicata. In termini matematici la lista dei parametri costituisce il dominio della funzione mentre il tipo del risultato ne è il codominio

19 Lista dei parametri La lista dei parametri è racchiusa tra due parentesi tonde, aperta e chiusa e consiste in una successione di dichiarazione di parametri formali, separate tra loro da una virgola. Ogni dichiarazione di parametro formale è costituita a sua volta da un identificatore di tipo di dato che può essere sia un tipo predefinito (int, char, double ) sia un tipo di dato definito dall utente (struct, enum, ). I parametri formali si chiamano così poiché non hanno valore proprio ma sono semplicemente dei riferimenti simbolici agli argomenti delle funzioni

20 Valore di ritorno Il valore di ritorno (risultato) di una funzione è il tipo di dato del risultato della funzione stessa Esso può essere di tipo predefinito o definito dall utente. In particolare una funzione non può restituire un array o funzioni ma può restituire un puntatore a qualsiasi tipo.

21 Dichiarazione di funzione La sintassi comune di una dichiarazione di funzione è la seguente: Dove [tipo_di_dato] [nome_della_funzione] ([lista di parametri]) [lista di parametri] = lista di dichiarazioni di variabili visibili dall interno e dall esterno della funzione double potenza( int x, int y); questa riga di codice dice che da qualche parte esiste una funzione potenza che riceve in ingresso due interi, esegue qualcosa e ritorna un double.

22 Dichiarazione locale Dopo la testata seguono le dichiarazioni locali in cui sono definiti tutti gli oggetti necessari alla realizzazione della funzionalità desiderata Esse seguono le stesse leggi per la costruzione della parte dichiarativa di un programma Si possono trovare quindi dichiarazioni di tipi, di costanti, di variabili e di altri sottoprogrammi

23 Corpo della funzione e return Infine si trova il corpo della funzione costruito con le medesime regole sintattiche del programma principale Al suo interno però si trova normalmente una o più istruzioni di return la cui sintassi è definita dalla parola chiave return seguita da una espressione. L istruzione return assegna alla variabile risultato (che può essere immaginata come identificata dal nome dellafunione) il valore dell espressione coinvolta nel return e fa sì che l esecuzione della funzione termini. L espressione coinvolta nell istruzione return è quindi del tipo del codominio della funzione (ovvero il tipo di dato restituito dalla funzione): il suo valore nell istante di esecuzione dell istruzione return sarà il risultato della funzione

24 Istruzione return Nel corpo di un sottoprogramma possono essere presenti più istruzioni return ma ovviamente solo la prima che si incontra durante l esecuzione del flusso di istruzioni nel sottoprogramma viene eseguita Se nessuna istruzione return è presente nel corpo della funzione o se quelle presenti non vengono eseguite (perché in rami condizionali non utilizzati), il sottoprogramma termina in corrispondenza del simbolo } che conclude il corpo della funzione: in tal caso però il risultato della funzione è indefinito e ciò provoca una segnalazione di errore.

25 Esempi di funzioni double fatturato_totale(elencofatture ef) { double totale; int cont; } totale=0; for (cont=0; cont < ef.numfatture;cont++) { totale=totale+ef.sequenza[cont].importo; } return totale; Questa funzione restituisce il valore del totale degli importi delle fatture appartenenti ad un elenco di fatture (ElencoFatture è un tipo di dato definito dall utente tramite struct). Si noti l uso delle variabili locali cont e totale che sono utilizzate esclusivamente allo scopo di memorizzare valori all interno della funzione

26 Esempio di funzione int RadiceIntera (int par) { int cont=0; } while (cont*cont <= par) { cont = cont +1; } return (cont - 1); Questa funzione produce la radice quadrata intera del parametro par, cioè il massimo intero il cui quadrato non sia superiore al valore di par. Si noti come se par è negativo, il risultato è -1 e questo valore può essere utilizzato per segnalare un uso improprio della fuinzione

27 Chiamata delle funzioni Una funzione viene applicata ad una serie di valori appartenenti al dominio della funzione e restituisce un risultato. Più precisamente, la sintassi di una chiamata di funzione consiste nel nome della funzione stessa seguito dalla lista dei parametri attuali racchiusa tra parentesi tonde. I parametri attuali indicano i valori degli argomenti rispetto ai quali la funzione deve essere calcolata. Ogni parametro può quindi essere una espressione qualsiasi, eventualmente contenente una chiamata di funzione.

28 Chiamata delle funzioni La corrispondenza tra parametri segue l ordine della dichiarazione: al primo parametro formale viene fatto corrispondere il primo parametro attuale di ogni chiamata e via di seguito. Da questo segue che il numero ed il tipo di dato di parametri attuali in ogni chiamata deve essere lo stesso di quello dei parametri formali. Il tipo dei parametri è fissato una volta per tutte dalla dichiarazione della funzione come abbiamo visto precedentemente.

29 Chiamata delle funzioni Esempi: x = sin (y) cos(pigreco alfa); x = cos (atan(y) beta ); RisultatoGestione = FatturatoTotale(ArchivioFatture) SommaCosti(ArchivioCosti); Det1 = Determinante(Matrice1); Det2 = Determinante(MatriceInversa(Matrice1)); TotaleAssoluto = Sommatoria(lista1) + Sommatoria(lista2); ElencoOrdinato = Ordina(Elenco); ecc

30 Prototipo delle funzioni All interno di un programma C una funzione può essere chiamata purchè risulti definita oppure dichiarata. Definizione e Dichiarazione non sono termini equivalenti: la dichiarazione di una funzione (normalmente chiamata prototipo) si limita a richiamare la testata nel modo spiegato precedentemente ed ha lo scopo di facilitare la compilazione e la comprensione del programma.

31 Prototipo delle funzioni Talvolta infatti la chiamata di una funzione precede nel codice la definizione della funzione (ossia l implementazione) mentre altre volte le funzioni utilizzate da un programma sono definite in file propri del sistema C. Le funzioni di libreria sono esempi di funzioni richiamabili da diversi programmi: - La loro definizione è contenuta in file messi a disposizione dal creatore della libreria e non è necessario ridefinire tali funzioni internamente al programma che desidera richiamarle

32 Parte dichiarativa del programma e delle funzioni Riconsiderando quanto detto circa le parti dichiarative del programma principale e delle funzioni di un programma C, esse possono contenere i seguenti elementi: - Dichiarazioni di costanti - Dichiarazioni di tipo - Dichiarazioni di variabili - Prototipi delle funzioni

33 Procedure

34 Procedure Non sempre le funzionalità di cui abbiamo bisogno possono essere descritte come funzioni matematiche Per esempio, supponiamo di voler stampare un elenco di fatture. Ciò deve essere fatto in maniera parametrica poiché può capitare di voler stampare elenchi diversi in momenti diversi: abbiamo bisogno di una operazione StampaFatture che ha in comune con una funzione il fatto di avere le fatture da stampare come parametri ma, diversamente da essa, ha come scopo non il calcolo di un valorema la produzione di un tabulato di stampa

35 Le procedure Vi sono alcuni casi in cui l effetto dell operazione non è ben descritto come il calcolo di una operazione matematica: - Inserimento di una nuova fattura in un archiviofatture: il risultato atteso non è un nuovo archiviofatture ma l aggiornamento di una variabile già esistente. - Ordinare una archivio di fatture secondo per esempio la data di emissione. L effetto di un sottoprogramma Ordina(archivio) non deve restituire un risultato ma deve modificare archivio in modo che gli elementi in esso contenuti siano ordinati per data. In conclusione in diverse occasioni il compito di una operazione non (o non è soltanto) quello di produrre un risultato di un certo tipo, ma è modificare lo stato, cioè il contenuto, del programma che ne chiede l esecuzione: in tali casi il sottoprogramma utilizzato è chiamato procedura

36 Procedura Le procedure sono del tutto simili alle funzioni. Hanno una parte dichiarativa composta da: - Header - Dichiarazioni variabili locali - Corpo La differenza è che una procedura, quindi, in generale, non restituisce un valore e quindi l header ha come valore di ritorno un tipo speciale: void Il tipo void può essere impiegato come tipo dei parametri formali nel caso non esistano parametri passati alla funzione o procedura

37 Chiamata delle procedure La chiamata ad una procedura è una istruzione uguale alla chiamata ad una funzione. Consiste ne: - Identificatore della procedura - Elenco dei parametri attuali fra parentesi tonde La differenza sta nel fatto che tale chiamata non produce come risultato un valore ma solamente la modifica di uno o più parametri attuali. I parametri attuali indicano i valori degli argomenti con i quali deve essere eseguita la procedura: ogni paramtero può essere costituito da un qualsiasi genera di espressione

38 Chiamata delle procedure La corrispondenza tra parametri formali e parametri attuali segue le stesse regole della chiamata delle funzioni: il rpimo parametro formale viene assegnato al primo parametro attuale e così via. Esempio: Typedef struct { String indirizzo; double ammontare; Data DataFattura; } DescrizioneFatture;

39 Chiamata delle procedure Typedef struct { int NumFatture; DescrizioneFatture Sequenza[MaxNumFatt]; } ElencoFatture; ElencoFatture ArchivioFatture; void inseriscifattura(descrizionefatture Fattura); boolean Precede(Data d1, Data d2); void main() { Data DataOdierna; DescrizioneFatture Fattura1,Fattura2; inseriscifattura(fattura1); if (Precede(Fattura2.DataFattura,DataOdierna)) { inseriscifattura(fattura2); } }

40 Chiamata delle procedure void inseriscifattura(descrizionefatture fattura) { if (ArchivioFatture.NumFatture == MaxNumFatture) { printf( L archivio è pieno ); } else { ArchivioFatture.NumFatture=ArchivioFatture.NumFatture+1; ArchivioFatture.Sequenza[ArchivioFatture.NumFatture-1]=fattura; } }

41 Passaggio di parametri

42 Passaggio di parametri Cosa succede quando si passa una variabile come parametro ad una funzione? Ossia, se all interno della funzione modifico il valore di quel parametro, il valore della variabile originaria viene modificato? La risposta è: dipende!! Esistono due modi per il passaggio dei parametri: - Per valore - Per riferimento

43 Passaggio di parametri per valore Quando è richiesto che i valori delle variabili non siano modificati dal corpo della funzione, quello che avviene è che il valore della variabile viene copiato nella variabile-parametro della funzione. In questo modo: - ogni modifica alla variabile locale non si riflette sulla variabile esterna - ogni modifica fatta alle variabili locali, però, va persa all uscita dalla funzione e solo il risultato ritornato è visibile dall esterno della funzione Questo metodo di passaggio dei parametri va sotto il nome di passaggio per copia o per valore

44 Passaggio di parametri per riferimento Quando invece è richiesto che le variabili interne alla funzione siano non una copia di quelle esterne, ma la stessa cosa, si parla di passaggio per riferimento: - In questo caso, la variabile locale assume il riferimento in memoria alla variabile esterna - Quindi ogni modifica ad essa è una modifica alla cella di memoria originale e permane anche alla chiusura dalla funzione Normalmente questa situazione è richiesta quando si ha un sottoprogramma che deve effettuare delle operazioni su un dato e non ritorna alcun valore: ES. aggiornamento del fatturato totale, ecc in questo caso il fatturato totale, una volta aggiornato deve rimanere tale, quindi è necessario operare l aggiornamento sulla variabile originale e non su una copia del valore

45 Passaggio di parametri Notiamo che il passaggio per valore richiede la copia della variabile nella nuova variabile locale, mentre il riferimento ha un costo costante, viene copiato comunque un indirizzo di memoria - Se stiamo passando dati strutturati particolarmente complessi, array di grandi dimensioni, ecc il passaggio per valore può essere molto più lento del passaggio per riferimento E anche vero però che il passaggio per valore è molto più safety rispetto all altro, dato che qualsiasi modifica, anche quella non voluta ed erronea non si riflette sul dato originario

46 Passaggio di parametri Il metodo utilizzato per il passaggio dei parametri cambia da linguaggio a linguaggio: - Il C e C++ utilizzano il passaggio per valore, ma forniscono dei tipi di dato che permettono di realizzare il passaggio per riferimento (puntatori e riferimenti) - Il JAVA utilizza il passaggio per riferimento. Il passaggio per valore può comunque essere effettuato costruendo ogni volta una copia del parametro e passare quella alla funzione.

47 Funzioni e procedure La differenza sul metodo di passaggio dei parametri stabilisce un altra fondamentale differenza tra una funzione ed una procedura: - Funzione: lo scopo principale è quello di utilizzare alcuni valori in ingresso per produrre un valore di uscita, senza modificare null altro passaggio per valore - Procedura: lo scopo principale è quello di operare delle operazioni sui parametri in ingresso che abbiano una semantica tale da poterle racchiudere in un corpo unico passaggio per riferimento Comunque la differenza è solamente formale: - In C++ o in JAVA non esistono metodi per dichiarare una funzione piuttosto che una procedura. In realtà il primo prevede solamente funzioni, il secondo procedure.

48 Passaggio di parametri per valore Spazio di memoria del chiamante int a copia Spazio di memoria del chiamato par1 Programma chiamante chiamata di funzione valore di ritorno modifica locale Funzione chiamata

49 Passaggio di parametri per riferimento Spazio di memoria del chiamante int a Programma chiamante riferimento modifica chiamata di funzione valore di ritorno Spazio di memoria del chiamato par1 modifica locale Funzione chiamata

50 La funzione main

51 Il corpo del programma Adesso che abbiamo acquisito il concetto di funzione è possibile descrivere la struttura completa di un programma (procedurale) Un programma procedurale è composto da: - Dichiarazioni di variabili - Dichiarazioni di funzioni (prototipi) - Implementazioni delle funzioni (anche su più file) - Corpo del programma Ma cosa s intende per corpo del programma? - Il corpo del programma è a sua volta una funzione globale particolare che utilizzando tutte le altre funzioni ed i dati a disposizione, assembla il tutto per eseguire il compito ell algoritmo

52 La funzione main In definitiva, un programma non è altro che una funzione dal prototipo particolare e fissato: - int main(int argc,char[] argv) C e C++ Questa funzione accetta due parametri in ingresso e restituisce un valore intero in uscita: - I due parametri in ingresso permettono di leggere eventuali parametri passati da linea di comando all applicazione - Es. il comando copy in windows accetta due parametri - copy file_a file_b argc=2, argv=[file_a,file_b] - Il valore di ritorno permette di stabilire se l esecuzione del programma è andata a buon fine o meno. Solitamente un programma ritorna 0 se esce correttamente, 1 se vi sono stati errori

53 Variabili globali e locali La dichiarazione di una variabile normalmente può avvenire in qualsiasi punto del programma, sempre però prima che la variabile sia utilizzata per la prima volta In particolare, la variabile può essere dichiarata fuori da qualsiasi funzione oppure all interno di una funzione (o procedura : - Nel primo caso, ambito globale, la variabile esiste in ogni parte del programma (con le debite eccezioni), a partire dal momento in cui il compilatore legge la riga di dichiarazione e la istanzia - Nel secondo caso, ambito locale, invece, la variabile esiste solamente all interno della funzione in cui è stata dichiarata e sarà deallocata all uscita della funzione stessa

54 Visibilità di variabili (scope) Ma cosa accade se una variabile locale ha lo stesso nome di una variabile globale? Quando la funzione è chiamata, con quel nome a quale variabile ci riferiamo, quella globale o quella locale? Risposta: la variabile più vicina, è quella a cui viene fatto riferimento con il nome ( nesting rule ) - Il campo di visibilità di una variabile (scope) è sempre quello ultimo in cui la variabile è stata dichiarata, anche se due variabili portano lo stesso nome Quindi durante l esecuzione di tutta la procedura, ogni riferimento alla variabile A sarà risolto con un riferimento alla variabile A locale alla procedura. Tale riferimento cessa non appena la procedura e lo scope relativo ad essa terminano

55 Lo spazio di memoria globale Per tutto quello che si è detto, anche le variabili dichiarate nella funzione principale sono variabili locali alla funzione main: - Un programma allora è composto da più spazi di memoria distinti, di cui solamente uno, lo spazio di memoria globale è condiviso in tutto il progetto Lo spazio di memoria globale è composto dalle variabili dichiarate fuori da ogni funzione, compresa la funzione principale (il main())

56 Schema di un programma procedurale Spazio di memoria del main Spazio di memoria globale Spazio di memoria delle funzioni f 1 int main(int,int) f 2 Chiamate di funzione Accessi alla memoria globale f n

57 Le funzioni nella CPU

58 Cambio di contesto Ma cosa succede a basso livello quando viene chiamata una funzione? La chiamata di una funzione genera un cambio di contesto (context switch) nella CPU: - Lo stato attuale della CPU deve essere salvato da qualche parte affinchè una volta eseguita la procedura sia possibile riprendere correttamente l esecuzione delle istruzioni - Anche i registri devono essere salvati dato che le istruzioni della procedura non devono assolutamente modificare i valori eterni alla procedura stessa Lo stato del processo viene allora salvato sullo stack di sistema

59 Lo stack Una parte di memoria centrale viene gestita come stack di sistema (pila) Alla chiamata di una procedura: - il contesto attuale viene inserito in cima allo stack: operazione push - Prepara la CPU ad eseguire la nuova procedura: Setta l istruzione da eseguire, il registro dati e quello indirizzi con i parametri passati alla procedura - La procedura esegue le istruzioni - Quando la procedura termina, il contesto in cima allo stack viene ripristinato: Operazione pop Lo stack memorizza le chiamate a procedura e le richiama in ordine inverso di memorizzazione

60 Stack Alla chiamata della funzione f, il contesto della funzione in esecuzione attualmente viene memorizzato in cima allo stack CPU f3 push f4 funzione in esecuzione f2 f1 main() stack f3 f2 f1 main() stack

61 Stack Quando poi la funzione termina, viene ripristinato l ultimo contesto inserito nello stack, la funzione f(t-1): pop f3 CPU f f2 funzione in esecuzione Funzioni chiamate e terminate f1 main() stack

62 Stack Quando anche la funzione f(t-1) termina, viene ripristinato il contesto di f(t-2), e così via pop f2 CPU f3 f1 funzione in esecuzione f Funzioni chiamate e terminate main() stack

63 Stack L ultimo contesto nello stack sarà quello relativo alla funzione main(). Quando questo termina, l applicazione termina. pop main() funzione in esecuzione CPU f1 f2 f3 empty stack f Funzioni chiamate e terminate

64 La ricorsione

65 La ricorsione Si parla di ricorsione quando all interno di una funzione P, viene richiamata P stessa, normalmente su un diverso set di dati La chiamata ricorsiva può essere sia esplicita che implicita: - Esplicita la funzione P è richiamata esplicitamente all interno del corpo di P stesso - Implicita la funzione P è richiamata attraverso la chiamata ad un altra funzione Q che contiene la chiamata a P A prima vista la cosa può apparire sorprendente dato che una funzione (o procedura) è dedita a risolvere un sottoproblema: - La ricorsione è come dire che per risolvere il sottoproblema P è necessario risolvere il sottoproblema P stesso!!

66 La ricorsione In realtà la programmazione ricorsiva a profonde radici concettuali derivanti dal fatto che per molti problemi la soluzione per un caso generico può essere ricavata sulla base della soluzione di un caso più semplice dello stesso problema : - L ordinamento di un array, il calcolo del fattoriale, ecc sono tipici problemi di questo tipo

67 Es. somma come ricorsione La ricorsione è nascosta in moltissime forme del ragionamento umano. Per esempio la somma tra due numeri può essere vista come ricorsione dell operatore successore(): - successore(x)=numero successivo ad x Algoritmo ricorsivo per l addizione - x+0 = x; - x+y = x+successore(y-1) = successore(x+y-1) = successore(1+2) = successore(sucessore(1+1)) = - = successore(successore(successore(1+0))) = - = successore(successore(successore(1))) = - = successore(successore(2)) = successore(3) = 4

68 Es. 1 Pesate Problema: date un gruppo di palline di forma identica e tutte di peso identico tranne una di peso maggiore delle altre, trovare la pallina più pesante utilizzando una bilancia ed il minor numero di pesate (supponiamo di avere un numero di palline multiplo di 3) Algoritmo: - Dividi il gruppo in tre gruppi di egual numero di palline e pesa due di questi gruppi - Se i due gruppi hanno lo stesso peso scartarli entrambi, altrimenti scartare il gruppo non pesato e quello sulla bilancia con il peso minore (la pallina cercata si troverà nel gruppo con peso maggiore) - Dividi il gruppo rimasto in tre sottogruppi e ripeti il procedimento finché i sottogruppi non contengano una sola palline: in tal caso l ultima pesata indica quale delle tre palline rimaste è quella cercata

69 Es. 1 Pesate Notiamo come l ultimo punto sia la ripetizione dell algoritmo su un set ridotto di dati fino a che non ci troviamo di fronte ad un caso notevole, di cui possiamo dare una immediata soluzione: - tre gruppi di una pallina ciascuno Per avere una visione più informatica dell algoritmo: - Se il gruppo di palline consiste di una sola pallina, la pallina è la soluzione cercata, altrimenti - Dividi il gruppo di palline in tre sottogruppi e poni due sottogruppi sulla bilancia - Se i due gruppi hanno peso uguale scartarli entrambi, altrimenti scartare il gruppo non pesato e quello di peso minore - Applica l algoritmo pesate al sottogruppo individuato

70 Es. 2 Successione di Fibonacci La successione di numeri di Fibonacci fu definita dal matematico come modello di crescita dei conigli in allevamento: - f0=0 - f1=1 - fn=fn-1 + fn-2, per n> 1 Es. calcolando f per i primi 6 numeri: - f0=0 - f1=1 - f2=f1+f0=1+0=1 - f3=f2+f1=1+1=2 - f4=f3+f2=2+1=3 - f5=f4+f3=3+2=5 -

71 Es. 3 Fattoriale Il fattoriale di un numero è la produttoria di tutti i numeri fino al numero stesso, escluso lo 0: - 5! = 5 x 4 x 3 x 2 x 1 = 120 Il fattoriale può essere espresso in forma ricorsiva: - 0! = 1 - n! = n x (n-1)! Infatti: - 5!=5 x (4 x 3 x 2 x 1) = 5 x 4! Anche il fattoriale è un tipico esempio di algoritmo ricorsivo

72 Es. 4 ricerca in un vettore Un esempio tipico di algoritmo di ricerca dati in un vettore ordinato è il seguente: - Se il vettore è composto da un solo elemento, confronta l elemento con D e se è uguale ritorna D altrimenti ritorna non trovato - Seleziona l elemento centrale P del vettore - Confronta il dato D da cercare con l elemento centrale P - Se D<P, ripeti l algoritmo sulla prima metà del vettore, altrimenti ripetilo sulla seconda

73 Es. 5 Sommatoria La sommatoria di una sequenza di n numeri può essere vista come la somma numero n-esimo alla sommatoria dei rimanenti (n-1) numeri: 0 i= 0 n a i = 0 n 1 a = a + a i n i i= 1 i= 1 La sommatoria comunque può essere risolta semplicemente con un ciclo, risparmiando così il carico aggiuntivo della ricorsione

74 Caso generale Si può generalizzare il concetto di ricorsione. Affinché un algoritmo sia scrivibile in forma ricorsiva, è necessario che: - l algoritmo abbia una soluzione banale, f(0)=0 - l algoritmo al passo n possa essere espresso come funzione del valore al passo (n-1) La condizione banale è necessarie per evitare una ricorsione infinita: Se infatti non esiste una condizione in cui siamo in grado di dare la soluzione, le iterazioni non terminano mai In questo caso, solitamente si verifica un errore di stack overflow, ovvero pila piena

75 Ricorsione e stack La ricorsione viene realizzata mantenendo nello stack la sequenza delle chiamate alla procedura che non possono essere risolte fino al caso banale Una volta trovata la soluzione banale questa viene passata a ritroso a tutte le istanze dell algoritmo sospese nello stack fino alla istanza finale che restituisce il risultato finale

76 Successione di Fibonacci Scriviamo l algoritmo ricorsivo per la successione di Fibonacci: - int fibonacci(int n) { - int ris=0; - if (n==0) return 0; - else if (n==1) return 1; - else ris = fibonacci(n-1) + fibonacci(n-2); - }

77 Fattoriale e sommatoria Scriviamo l algoritmo ricorsivo per il calcolo del fattoriale: - int fatt(int n) { - int ris=0; - if (n==0) return 1; - else ris = n * fatt(n-1); - return ris; - } Scriviamo l algoritmo ricorsivo per la sommatoria: int sum(int a[]) { int ris=0; if (vuota(a)==true) return 0; else ris = testa(a) + coda(a); return ris; }

78 Fattoriale 1 y=fatt(5) CPU fatt(2) push fatt(1) funzione in esecuzione fatt(3) fatt(4) fatt(5) stack fatt(2) fatt(3) fatt(4) fatt(5) stack

79 Fattoriale 2 y=fatt(5) pop fatt(2) CPU fatt(1)=1 fatt(3) funzione in esecuzione Funzioni chiamate e terminate fatt(4) fatt(5) stack

80 Fattoriale 3 y=fatt(5) pop fatt(5) funzione in esecuzione CPU fatt(4)=24 fatt(3)=6 fatt(2)=2 empty stack fatt(1)=1 Funzioni chiamate e terminate

81 Programmazione ad oggetti

82 Paradigma ad oggetti Come detto, i linguaggi di programmazione procedurali sono stati quasi tutti sostituiti dalle rispettive versioni ad oggetti (tranne nei casi in cui la programmazione ad oggetti non è consigliata, ad esempio programmazione di basso livello, S.O., programmazione PLC ecc ) Ma cos è questo diverso tipo di programmazione? In cosa differisce dalla programmazione classica?

83 Object Oriented Programming (OOP) La maggior parte dei programmi utili non manipola soltanto numeri e stringhe, ma gestisce dati più complessi e più aderenti alla realtà: - Conti bancari, informazioni sugli impiegati, forme grafiche L idea della programmazione ad oggetti è di rappresentare questi dati così come sono anche nel linguaggio di programmazione: gli oggetti o classi La programmazione ad oggetti estende al massimo l idea di dato strutturato presente nella programmazione classica: - una classe (o oggetto) è un tipo di dato strutturato a cui sono associate variabili e funzioni

84 Object Oriented Programming (OOP) Il programmatore individua degli oggetti nella applicazione che deve progettare: - Conto corrente, client e server, documento, ecc Ogni oggetto ha delle proprietà e delle capacità (o funzioni) L applicazione è poi costruita facendo interagire correttamente gli oggetti esistenti nell ambiente che si va a progettare Ma la funzione main() che fine ha fatto? Se non si usano più le procedure/funzioni globali, come si rende eseguibile un programma? Cioè qual è il corpo principale dell applicazione? Due filosofie differenti per rispondere a queste domande: il C++ ed il JAVA

85 Object Oriented Programming(OOP) Il C++ ha mantenuto comunque una certa compatibilità con i linguaggi procedurali: - in C++ è ancora possibile infatti definire funzioni globali, variabili globali e quindi la funzione main() rimane una funzione definita globalmente e cercata dal compilatore per rendere eseguibile un programma Il JAVA ha seguito un altro approccio: In JAVA non esistono funzioni globali, cioè esterne da qualsiasi oggetto, ma ogni funzione o variabile deve appartenere ad un oggetto (o meglio classe): è possibile però definire una funzione main() per ogni classe e rendere eseguibile la classe stessa In compilazione, vengono creati degli oggetti eseguibili (non un unico programma). La scelta di cosa far partire viene fatta dall utente selezionando l oggetto eseguibile desiderato.

86 Object Oriented Programming(OOP) Es di oggetti JAVA ObjectA: -datoy -funzione1 -funzione2 -main() ObjectB: -datox -funzione1 -funzione2 -funzione3 -main() Normalmente quello che accade in JAVA è che viene creato un oggetto che rappresenta l applicazione e che contiene la funzione main(): - Eseguire l applicazione significa lanciare il main() di tale oggetto

Funzioni in C. Violetta Lonati

Funzioni in C. Violetta Lonati Università degli studi di Milano Dipartimento di Scienze dell Informazione Laboratorio di algoritmi e strutture dati Corso di laurea in Informatica Funzioni - in breve: Funzioni Definizione di funzioni

Dettagli

Appunti del corso di Informatica 1. 6 Introduzione al linguaggio C

Appunti del corso di Informatica 1. 6 Introduzione al linguaggio C Università di Roma Tre Dipartimento di Matematica e Fisica Corso di Laurea in Matematica Appunti del corso di Informatica 1 (IN110 Fondamenti) 6 Introduzione al linguaggio C Marco Liverani (liverani@mat.uniroma3.it)

Dettagli

Appunti del corso di Informatica 1 (IN110 Fondamenti) 6 Introduzione al linguaggio C

Appunti del corso di Informatica 1 (IN110 Fondamenti) 6 Introduzione al linguaggio C Università di Roma Tre Facoltà di Scienze M.F.N. Corso di Laurea in Matematica Appunti del corso di Informatica 1 (IN110 Fondamenti) 6 Introduzione al linguaggio C Marco Liverani (liverani@mat.uniroma3.it)

Dettagli

AA 2006-07 LA RICORSIONE

AA 2006-07 LA RICORSIONE PROGRAMMAZIONE AA 2006-07 LA RICORSIONE AA 2006-07 Prof.ssa A. Lanza - DIB 1/18 LA RICORSIONE Il concetto di ricorsione nasce dalla matematica Una funzione matematica è definita ricorsivamente quando nella

Dettagli

INFORMATICA 1 L. Mezzalira

INFORMATICA 1 L. Mezzalira INFORMATICA 1 L. Mezzalira Possibili domande 1 --- Caratteristiche delle macchine tipiche dell informatica Componenti hardware del modello funzionale di sistema informatico Componenti software del modello

Dettagli

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

12 - Introduzione alla Programmazione Orientata agli Oggetti (Object Oriented Programming OOP) 12 - Introduzione alla Programmazione Orientata agli Oggetti (Object Oriented Programming OOP) Programmazione e analisi di dati Modulo A: Programmazione in Java Paolo Milazzo Dipartimento di Informatica,

Dettagli

Introduzione alla programmazione in C

Introduzione alla programmazione in C Introduzione alla programmazione in C Testi Consigliati: A. Kelley & I. Pohl C didattica e programmazione B.W. Kernighan & D. M. Ritchie Linguaggio C P. Tosoratti Introduzione all informatica Materiale

Dettagli

Una funzione è detta ricorsiva se chiama, direttamente o indirettamente, se stessa. In C tutte le funzioni possono essere usate ricorsivamente.

Una funzione è detta ricorsiva se chiama, direttamente o indirettamente, se stessa. In C tutte le funzioni possono essere usate ricorsivamente. Ricorsione Funzioni ricorsive Una funzione è detta ricorsiva se chiama, direttamente o indirettamente, se stessa. In C tutte le funzioni possono essere usate ricorsivamente. Un esempio di funzione ricorsiva

Dettagli

Algoritmi e Strutture Dati

Algoritmi e Strutture Dati schifano@fe.infn.it Laurea di Informatica - Università di Ferrara 2011-2012 [1] Strutture dati Dinamiche: Le liste Una lista è una sequenza di elementi di un certo tipo in cui è possibile aggiungere e/o

Dettagli

Elementi di Informatica

Elementi di Informatica Università degli Studi di Udine Facoltà di Ingegneria CORSO DI LAUREA IN SCIENZE dell ARCHITETTURA Elementi di Informatica Algoritmi, e Programmi D. Gubiani 29 marzo 2010 D. Gubiani Algoritmi, e Programmi

Dettagli

Allocazione dinamica della memoria - riepilogo

Allocazione dinamica della memoria - riepilogo Università degli studi di Milano Dipartimento di Scienze dell Informazione Laboratorio di algoritmi e strutture dati Corso di laurea in Informatica In breve Storage duration Allocazione dinamica della

Dettagli

int f(char *s, short n, float x) {... } /* definizione di f */ int f(char *, short, float); /* prototipo di f */

int f(char *s, short n, float x) {... } /* definizione di f */ int f(char *, short, float); /* prototipo di f */ Prototipi di funzione Il prototipo di una funzione costituisce una dichiarazione della funzione, e come tale fornisce al compilatore le informazioni necessarie a gestire la funzione stessa. Nella definizione

Dettagli

1 introdurre le monete per l importo necessario. 2 selezionare la quantità di zucchero. 3 selezionare la bevanda desiderata

1 introdurre le monete per l importo necessario. 2 selezionare la quantità di zucchero. 3 selezionare la bevanda desiderata Esempi di Problema: Prendere un Caffè al Distributore Università degli Studi di Udine Facoltà di Ingegneria CORSO DI LAUREA IN SCIENZE dell ARCHITETTURA Elementi di Informatica, e Programmi D. Gubiani

Dettagli

La selezione binaria

La selezione binaria Andrea Marin Università Ca Foscari Venezia Laurea in Informatica Corso di Programmazione part-time a.a. 2011/2012 Introduzione L esecuzione di tutte le istruzioni in sequenza può non è sufficiente per

Dettagli

Linguaggio C - Funzioni

Linguaggio C - Funzioni Linguaggio C - Funzioni Funzioni: Il linguaggio C è di tipo procedurale; ogni programma viene suddiviso in sottoprogrammi, ognuno dei quali svolge un determinato compito. I sottoprogrammi si usano anche

Dettagli

13 - Gestione della Memoria nella Programmazione Orientata agli Oggetti

13 - Gestione della Memoria nella Programmazione Orientata agli Oggetti 13 - Gestione della Memoria nella Programmazione Orientata agli Oggetti Programmazione e analisi di dati Modulo A: Programmazione in Java Paolo Milazzo Dipartimento di Informatica, Università di Pisa http://www.di.unipi.it/

Dettagli

Università degli Studi di Cassino Corso di Fondamenti di Informatica Puntatori. Anno Accademico 2010/2011 Francesco Tortorella

Università degli Studi di Cassino Corso di Fondamenti di Informatica Puntatori. Anno Accademico 2010/2011 Francesco Tortorella Corso di Informatica Puntatori Anno Accademico 2010/2011 Francesco Tortorella Variabili, registri ed indirizzi Abbiamo visto che la definizione di una variabile implica l allocazione (da parte del compilatore)

Dettagli

Fondamenti di Informatica e Laboratorio T-AB T-16 Progetti su più file. Funzioni come parametro. Parametri del main

Fondamenti di Informatica e Laboratorio T-AB T-16 Progetti su più file. Funzioni come parametro. Parametri del main Fondamenti di Informatica e Laboratorio T-AB T-16 Progetti su più file. Funzioni come parametro. Parametri del main Paolo Torroni Dipartimento di Elettronica, Informatica e Sistemistica Università degli

Dettagli

Algebra di Boole: Concetti di base. Fondamenti di Informatica - D. Talia - UNICAL 1. Fondamenti di Informatica

Algebra di Boole: Concetti di base. Fondamenti di Informatica - D. Talia - UNICAL 1. Fondamenti di Informatica Fondamenti di Informatica Algebra di Boole: Concetti di base Fondamenti di Informatica - D. Talia - UNICAL 1 Algebra di Boole E un algebra basata su tre operazioni logiche OR AND NOT Ed operandi che possono

Dettagli

Corso di Informatica

Corso di Informatica Corso di Informatica Modulo T3 1-Sottoprogrammi 1 Prerequisiti Tecnica top-down Programmazione elementare 2 1 Introduzione Lo scopo di questa Unità è utilizzare la metodologia di progettazione top-down

Dettagli

Ricorsione. Laboratorio di Programmazione II Corso di Laurea in Bioinformatica Dipartimento di Informatica - Università di Verona.

Ricorsione. Laboratorio di Programmazione II Corso di Laurea in Bioinformatica Dipartimento di Informatica - Università di Verona. Laboratorio di Programmazione II Corso di Laurea in Bioinformatica Dipartimento di Informatica - Università di Verona Sommario Implementazione di Utilizzo ricorsione per processare dati in java vs. multipla

Dettagli

Programma di Paradigmi e possibili domande. Capitolo 1

Programma di Paradigmi e possibili domande. Capitolo 1 Definizione di macchina astratta Programma di Paradigmi e possibili domande Capitolo 1 Una macchina astratta per il linguaggio L detta ML, è un qualsiasi insieme di algoritmi e strutture dati che permettono

Dettagli

Gli algoritmi: definizioni e proprietà

Gli algoritmi: definizioni e proprietà Dipartimento di Elettronica ed Informazione Politecnico di Milano Informatica e CAD (c.i.) - ICA Prof. Pierluigi Plebani A.A. 2008/2009 Gli algoritmi: definizioni e proprietà La presente dispensa e da

Dettagli

FONDAMENTI di INFORMATICA L. Mezzalira

FONDAMENTI di INFORMATICA L. Mezzalira FONDAMENTI di INFORMATICA L. Mezzalira Possibili domande 1 --- Caratteristiche delle macchine tipiche dell informatica Componenti hardware del modello funzionale di sistema informatico Componenti software

Dettagli

I tipi di dato astratti

I tipi di dato astratti I tipi di dato astratti.0 I tipi di dato astratti c Diego Calvanese Fondamenti di Informatica Corso di Laurea in Ingegneria Elettronica A.A. 001/00.0 0 I tipi di dato astratti La nozione di tipo di dato

Dettagli

Sommario. Definizione di informatica. Definizione di un calcolatore come esecutore. Gli algoritmi.

Sommario. Definizione di informatica. Definizione di un calcolatore come esecutore. Gli algoritmi. Algoritmi 1 Sommario Definizione di informatica. Definizione di un calcolatore come esecutore. Gli algoritmi. 2 Informatica Nome Informatica=informazione+automatica. Definizione Scienza che si occupa dell

Dettagli

Laboratorio di Algoritmi e Strutture Dati

Laboratorio di Algoritmi e Strutture Dati Laboratorio di Algoritmi e Strutture Dati Docente: Camillo Fiorentini 18 dicembre 2007 Esercizio 1: rappresentazione di una tabella di occorrenze L obiettivo è quello di rappresentare in modo efficiente

Dettagli

Connessione ad internet

Connessione ad internet Introduzione al C++ Connessione ad internet Istruzioni per la connessione internet: - una volta connessi, aprire un browser (firefox) - in Modifica/preferenze/avanzate/rete/impostazioni - attivare la modalità

Dettagli

Strutture. Strutture e Unioni. Definizione di strutture (2) Definizione di strutture (1)

Strutture. Strutture e Unioni. Definizione di strutture (2) Definizione di strutture (1) Strutture Strutture e Unioni DD cap.10 pp.379-391, 405-406 KP cap. 9 pp.361-379 Strutture Collezioni di variabili correlate (aggregati) sotto un unico nome Possono contenere variabili con diversi nomi

Dettagli

GESTIONE INFORMATICA DEI DATI AZIENDALI

GESTIONE INFORMATICA DEI DATI AZIENDALI GESTIONE INFORMATICA DEI DATI AZIENDALI Alberto ZANONI Centro Vito Volterra Università Tor Vergata Via Columbia 2, 00133 Roma, Italy zanoni@volterra.uniroma2.it Rudimenti di programmazione Programming

Dettagli

Corso di Visual Basic (Parte 9)

Corso di Visual Basic (Parte 9) Corso di Visual Basic (Parte 9) di Maurizio Crespi La nona lezione del corso dedicato alla programmazione in Visual Basic si pone lo scopo di illustrare le funzioni definibili dall'utente e il concetto

Dettagli

Scrivere un programma in Java

Scrivere un programma in Java Programmare in JAVA Leonardo Rigutini Dipartimento Ingegneria dell Informazione Università di Siena Via Roma 56 53100 SIENA uff. 0577 234850 - interno: 7102 Stanza 119 rigutini@dii.unisi.it http://www.dii.unisi.it/~rigutini/

Dettagli

Agent and Object Technology Lab Dipartimento di Ingegneria dell Informazione Università degli Studi di Parma. Fondamenti di Informatica

Agent and Object Technology Lab Dipartimento di Ingegneria dell Informazione Università degli Studi di Parma. Fondamenti di Informatica Agent and Object Technology Lab Dipartimento di Ingegneria dell Informazione Università degli Studi di Parma Fondamenti di Informatica Linguaggi di Programmazione Michele Tomaiuolo Linguaggi macchina I

Dettagli

Tecniche avanzate di sintesi di algoritmi: Programmazione dinamica Algoritmi greedy

Tecniche avanzate di sintesi di algoritmi: Programmazione dinamica Algoritmi greedy Tecniche avanzate di sintesi di algoritmi: Programmazione dinamica Algoritmi greedy Dr Maria Federico Programmazione dinamica Solitamente usata per risolvere problemi di ottimizzazione il problema ammette

Dettagli

Corso di Laurea in INFORMATICA

Corso di Laurea in INFORMATICA Corso di Laurea in INFORMATICA Algoritmi e Strutture Dati MODULO 2. Algebre di dati Dati e rappresentazioni, requisiti delle astrazioni di dati, costrutti. Astrazioni di dati e dati primitivi. Specifica

Dettagli

Tipi di Dato Ricorsivi

Tipi di Dato Ricorsivi Tipi di Dato Ricorsivi Luca Abeni September 2, 2015 1 Tipi di Dato Vari linguaggi di programmazione permettono all utente di definire nuovi tipi di dato definendo per ogni nuovo tipo l insieme dei suoi

Dettagli

La ricorsione. Politecnico di Milano Sede di Cremona

La ricorsione. Politecnico di Milano Sede di Cremona La ricorsione Politecnico di Milano Sede di Cremona Gianpaolo Cugola Dipartimento di Elettronica e Informazione cugola@elet.polimi.it http://www.elet.polimi.it/~cugola Definizioni ricorsive Sono comuni

Dettagli

Concetto di Funzione e Procedura METODI in Java

Concetto di Funzione e Procedura METODI in Java Fondamenti di Informatica Concetto di Funzione e Procedura METODI in Java Fondamenti di Informatica - D. Talia - UNICAL 1 Metodi e Sottoprogrammi Mentre in Java tramite le classi e gli oggetti è possibile

Dettagli

Ricorsione. (da lucidi di Marco Benedetti)

Ricorsione. (da lucidi di Marco Benedetti) Ricorsione (da lucidi di Marco Benedetti) Funzioni ricorsive Dal punto di vista sintattico, siamo in presenza di una funzione ricorsiva quando all interno della definizione di una funzione compaiono una

Dettagli

Ricorsione. Corso di Fondamenti di Informatica

Ricorsione. Corso di Fondamenti di Informatica Dipartimento di Informatica e Sistemistica Antonio Ruberti Sapienza Università di Roma Ricorsione Corso di Fondamenti di Informatica Laurea in Ingegneria Informatica (Canale di Ingegneria delle Reti e

Dettagli

Linguaggi e Paradigmi di Programmazione

Linguaggi e Paradigmi di Programmazione Linguaggi e Paradigmi di Programmazione Cos è un linguaggio Definizione 1 Un linguaggio è un insieme di parole e di metodi di combinazione delle parole usati e compresi da una comunità di persone. È una

Dettagli

JAVASCRIPT. Tale file è associato alla pagina web mediante il tag