Scomposizione funzionale

Slides:



Advertisements
Presentazioni simili
Programmazione ad oggetti
Advertisements

Funzioni e procedure Ogni linguaggio di programmazione ad alto livello mette a disposizione del programmatore questi strumenti, ed il C non è da meno!
Prof. Rebecca Montanari Anno accademico 2011/2012
Sottoprogrammi: funzioni e procedure
Lezione 8 Anno accademico Titolare corso: Prof. Costanza Torricelli
© 2007 SEI-Società Editrice Internazionale, Apogeo Unità E1 Dallanalisi del problema alla definizione dellalgoritmo.
Analisi – Progettazione - Programmazione
Linguaggi algoritmici
Recupero debito quarto anno Primo incontro
Classe III A A.s – 2011 Programma di Informatica 5 ore settimanali (3 laboratorio) Docenti –Prof. Alberto Ferrari –Prof. Alberto Paganuzzi.
© 2007 SEI-Società Editrice Internazionale, Apogeo Unità G1 Dati strutturati.
Ripasso R1 Dati strutturati.
Array multidimensionali
Procedure e funzioni A. Ferrari.
LS Tron Classe 4TC – as 2006/07 LORGANIZZAZIONE DEI PROGRAMMI UD. 8 p. 282.
I DATI LE ISTRUZIONI LE STRUTTURE FONDAMENTALI
ITIS LATTANZIO Unità Didattica Materia Informatica Funzioni in C++
Algoritmi e Programmazione
Lez. 31 Universita' di Ferrara Facolta' di Scienze Matematiche, Fisiche e Naturali Laurea Specialistica in Informatica Algoritmi Avanzati Programmazione.
Lez. 41 Universita' di Ferrara Facolta' di Scienze Matematiche, Fisiche e Naturali Laurea Specialistica in Informatica Algoritmi Avanzati Programmazione.
1 Istruzioni, algoritmi, linguaggi. 2 Algoritmo per il calcolo delle radici reali di unequazione di 2 o grado Data lequazione ax 2 +bx+c=0, quali sono.
Indirizzi delle variabili A ogni variabile sono associati tre concetti fondamentali: il valore memorizzato; il tipo dati di appartenenza; lindirizzo. Il.
Iterazione enumerativa (for)
Informatica Problema Algoritmo Programma
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE Funzioni e Procedure Marco D. Santambrogio – Ver. aggiornata al 18 Aprile 2012.
Informatica 2. Concetti fondamentali di programmazione Programmare vuol dire scrivere un algoritmo in un linguaggio che faccia funzionare un calcolatore.
Corso di Laurea in Biotecnologie Informatica (Programmazione)
Corso di Informatica (Programmazione)
Introduzione alla programmazione l
Unità Didattica 1 Algoritmi
Unità Didattica 2 I Linguaggi di Programmazione
Primi Elementi di Programmazione in C++
Strutture di controllo in C -- Flow Chart --
Fondamenti di Informatica Algoritmi
Gli algoritmi.
Elementi di Informatica
Elementi di Informatica
ITIS LATTANZIO Unità Didattica Materia Informatica Funzioni in C++
Dall’algoritmo al programma.
ELEMENTI DI PROGRAMMAZIONE
Algoritmi e Programmazione strutturata
INFORMATICA MATTEO CRISTANI.
Linguaggio C++ Fondamenti Un primo semplice esempio:
Un esempio: Calcolo della potenza n-esima di un numero reale
Sistemi e Tecnologie Informatiche Requisiti per la realizzazione di un buon programma.
Lo sviluppo top down Le funzioni
Ingegneria del software Modulo 2 -Il software come prodotto Unità didattica 2 -I costi del software Ernesto Damiani Università degli Studi di Milano Lezione.
BIOINFO3 - Lezione 15 ISTRUZIONI
ECDL Patente europea del computer
Programma di Informatica Classi Prime
COME RAGIONA UN COMPUTER
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE Funzioni e Procedure Marco D. Santambrogio – Ver. aggiornata al 3 Aprile 2015.
R 255 G 211 B 8 R 255 G 175 B 0 R 127 G 16 B 162 R 163 G 166 B 173 R 104 G 113 B 122 R 234 G 234 B 234 R 175 G 0 B 51 R 0 G 0 B 0 R 255 G 255 B 255 Supporting.
Rappresentazione degli algoritmi
La ricorsione.
Algoritmi.
Realizzazione software
Il software Claudia Raibulet
Algoritmi e Programmazione (in C) Stefano Cagnoni e Monica Mordonini
Informatica 4 La ricorsione. Definizione di ricorsione Ricorsione è la proprietà di quei programmi che, all’interno delle istruzioni che li compongono,
Problemi, algoritmi e programmazione
Dal problema al programma
ALGORITMI Dal problema al programma Definizione di algoritmo
Dal problema al programma
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE Algoritmi e basi del C Marco D. Santambrogio – Ver. aggiornata al 24 Agosto 2015.
GLI ALGORITMI Appunti preparati dalla prof.ssa Maria D’Angelo.
Informatica Problemi e algoritmi. una situazione che pone delle domande cui si devono dare risposte. Col termine problema o situazione problematica s’indica.
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE Funzioni e Procedure Marco D. Santambrogio – Ver. aggiornata al 4 Aprile 2016.
Unità di apprendimento 6 Dal problema al programma.
Unità di apprendimento 6
Transcript della presentazione:

Scomposizione funzionale Unità G2 Scomposizione funzionale

Obiettivi Comprendere il concetto di programmazione modulare Conoscere procedure e funzioni Comprendere il concetto di visibilità delle variabili Conoscere il concetto di funzione parametrica Conoscere le tecniche di passaggio di parametri Conoscere il significato di ricorsività Conoscere il significato di conversione di tipo Essere in grado di progettare procedure e funzioni Essere in grado di effettuare il passaggio di parametri per valore e per riferimento Essere in grado di realizzare funzioni ricorsive Essere in grado di effettuare la conversione di tipo

Progettazione modulare La difficoltà nell’affrontare un problema e nel descrivere i metodi di risoluzione è proporzionale alla sua dimensione. La tecnica dei raffinamenti successivi suggerisce di scomporre il problema in problemi più semplici (sottoproblemi) … e di applicare anche a questi sottoproblemi la stessa tecnica fino ad ottenere problemi facilmente risolvibili Questa tecnica è definita top-down: Si parte da una visione globale del problema (alto livello di astrazione) [top] Poi si scende nel dettaglio dei sottoproblemi diminuendo il livello di astrazione [down] Viene fornita inizialmente una soluzione del problema che non si basa però su operazioni elementari, ma sulla soluzione di sottoproblemi

Un semplice esempio Problema: si vuole conoscere il costo per la verniciatura di tre pannelli Dati di input: dimensione dei pannelli costo della vernice al mq Dato di output: costo della vernice necessaria per completare l’opera

Top-down

La scomposizione in sottoproblemi Se il sottoproblema è semplice allora viene risolto, viene cioè scritto l’algoritmo di risoluzione Se il sottoproblema è complesso viene riapplicato lo stesso procedimento scomponendolo in sottoproblemi più semplici Diminuisce il livello di astrazione (si affrontano problemi sempre più concreti) Diminuisce il livello di complessità (i sottoproblemi devono essere più semplici del problema che li ha originati) Fino ad arrivare alla stesura di tutti gli algoritmi necessari

Moduli modulo = codice di implementazione dell’algoritmo di risoluzione di un sottoproblema Si parla quindi di progettazione e di programmazione modulare Introduzione di una nuova complessità: l’interazione tra i moduli; perché il problema sia risolto nella sua interezza i moduli devono infatti necessariamente comunicare tra loro. Perché questa nuova complessità sia governabile i moduli devono essere il più possibile indipendenti l’uno dall’altro e le interazioni definite da regole semplici e chiare.

Procedure Gli strumenti messi a disposizione dai vari linguaggi per la programmazione modulare sono le procedure e le funzioni, per questa ragione si parla di scomposizione funzionale. La procedura racchiude il codice necessario alla soluzione di un sottoproblema (modulo) Individuiamo due fasi: Dichiarazione della procedura: fase in cui viene definito il suo nome e l’insieme delle istruzioni che la compongono Esecuzione (chiamata) della procedura: fase in cui vengono eseguite le istruzioni che la compongono

Dichiarazione e definizione di procedura E’ la fase in cui viene definito il nome (<NomeProcedura>) e l’insieme delle istruzioni Pseudolinguaggio Procedura <NomeProcedura> <istruzioni> <…> Fineprocedura <NomeProcedura> Linguaggio C <NomeProcedura> () { }

Esecuzione (chiamata della procedura) In qualunque punto del programma può essere invocata (chiamata) la procedura La chiamata è inserita nel programma mediante una istruzione composta dal nome della procedura La chiamata provoca l’interruzione momentanea dell’esecuzione del programma, l’esecuzione del codice interno alla procedura e la ripresa poi del programma dall’istruzione successiva alla chiamata Nel programma è possibile chiamare più volte una procedura

Un problema d’esempio Problema: Per la valutazione di una prova scritta viene fornito il numero degli studenti ed il voto ottenuto da ognuno di questi. Viene controllato che ogni voto sia ammissibile (non sono ammessi voti minori di 0 e maggiori di 10) poi viene calcolata la valutazione media Input: numero studenti, voti degli studenti. Output: voto medio

Algoritmo VotoMedio /* Procedura che visualizza un messaggio di errore */ // dichiarazione e definizione della procedura Procedura messaggioErrore Scrivi("Errore nell'immissione di un dato") Scrivi("Immetterlo di nuovo. Corretto per favore!") FineProcedura messaggioErrore voto Di Tipo Intero //voto di uno studente sommaVoti Di Tipo Reale //somma dei voti numeroStudenti Di Tipo Intero //numero degli studenti s Di Tipo Intero //variabile di ciclo  Ripeti Scrivi("Quanti studenti compongono la classe: ") Leggi(numeroStudenti) Se (numeroStudenti<=0) Allora messaggioErrore // chiamata della procedura FineSe Finquando (numeroStudenti<=0) sommaVoti<-0; //inizializzazione /* Richiesta voti degli studenti */ Per s da 1 a numeroStudenti Ripeti Scrivi("Voto studente n. ", s); Leggi(voto); Se (voto<0 || voto>10) Allora messaggioErrore // chiamata della procedura Altrimenti sommaVoti<-sommaVoti+voto FineSe Finquando ( voto<0 || voto>10 ) FinePer Scrivi("Il voto medio ottenuto e' ", sommaVoti/numeroStudenti); FineAlgoritmo VotoMedio

/* Voto medio */ #include <stdio.h> /* Funzione che visualizza un messaggio di errore */ // dichiarazione e definizione della procedura messaggioErrore() { printf("\nErrore nell'immissione di un dato\n"); printf("Immetterlo di nuovo. Corretto per favore!\n\n"); } main() int voto; //voto di uno studente float sommaVoti; //somma dei voti int numeroStudenti; //numero degli studenti int s; //variabile di ciclo do printf("Quanti studenti compongono la classe: "); scanf("%d", &numeroStudenti); if(numeroStudenti<=0) messaggioErrore(); // chiamata della procedura while (numeroStudenti<=0); sommaVoti=0; //inizializzazione /* Richiesta voti degli studenti */ for(s=1; s<=numeroStudenti; s++) { do printf("Voto studente n. %d: ", s); scanf("%d", &voto); if(voto<0 || voto>10) messaggioErrore(); // chiamata della procedura else sommaVoti+=voto; } while(voto<0 || voto>10); printf("Il voto medio ottenuto e' %f\n", sommaVoti/numeroStudenti);

/* Voto medio */ #include <iostream.h> #include <conio.h> /* Funzione che visualizza un messaggio di errore */ // dichiarazione e definizione della procedura messaggioErrore() { cout<<endl<<"Errore nell'immissione di un dato"<<endl; cout<<endl<<"Immetterlo di nuovo. Corretto per favore!"; } main() int voto; //voto di uno studente float sommaVoti; //somma dei voti int numeroStudenti; //numero degli studenti int s; //variabile di ciclo (studente)  do cout<<"Quanti studenti compongono la classe: "; cin>>numeroStudenti; if(numeroStudenti<=0) messaggioErrore(); // chiamata della procedura while (numeroStudenti<=0); sommaVoti=0; //inizializzazione /* Richiesta voti degli studenti */ for(s=1; s<=numeroStudenti; s++) { do cout<<"Voto studente n. "<<s<<" "; cin>>voto; if(voto<0 || voto>10) messaggioErrore(); // chiamata della procedura else sommaVoti+=voto; } while(voto<0 || voto>10); cout<<"Il voto medio ottenuto e' "<<sommaVoti/numeroStudenti; getch();

Riusabilità del codice Identiche porzioni di codice sono spesso utilizzate più volte all’interno di un programma La duplicazione pone due tipi di problemi: Aumento della lunghezza del codice e quindi minore leggibilità Difficoltà nell’apportare modifiche che devono essere effettuate in tutte le copie del codice Con le procedure si evita di duplicare parti del codice sorgente, quando si chiama o invoca una procedura si esegue il codice corrispondente. A ogni nuova chiamata il suo codice è eseguito nuovamente.

Scambio di dati fra programma e procedura Nell’esempio precedente la procedura messaggioErrore non scambiava nessun dato con il programma chiamante Molto spesso si rende necessario uno scambio di dati fra il programma e la procedura e fra la procedura e il programma chiamante I linguaggi di programmazione offrono vari metodi per realizzare questo scambio

Variabili globali Il metodo più semplice per scambiare informazioni è l’uso di uno spazio di memoria comune. La visibilità di una variabile definisce le parti del programma in cui questa è utilizzabile Una variabile locale è visibile solo all’interno di una procedura Una variabile globale è visibile in tutto il programma

Variabili locali in linguaggio C Avrete notato che la struttura di un programma C prevede un main che ha la stessa struttura di una procedura In effetti main è una procedura particolare, la procedura principale Ogni variabile dichiarata all’interno di una procedura è locale e visibile solo all’interno di questa Ogni variabile dichiarata esternamente alle procedure di un programma è globale e quindi visibile in ogni punto

Un esempio di scambio di dati Riprendiamo un problema affrontato nell’unità E1: determinare se un numero è primo Il procedimento utilizzato cerca il minimo divisore intero maggiore di 1 del numero, se è uguale al numero stesso allora il numero è primo.

/* Controllo se un numero è primo */ #include <stdio.h> int numero; //numero da analizzare (variabile globale) int divisore; //divisore trovato maggiore di 1 (globale) /* Procedura che individua il piu' piccolo divisore maggiore di 1 */ // dichiarazione e definizione della procedura divisoreMaggiore1() { int resto; //variabile locale divisore = 1; do divisore=divisore+1; resto = numero % divisore; } while(resto!=0); main() { printf("Immetti un numero intero positivo: "); scanf("%d", &numero); divisoreMaggiore1(); if(divisore==numero) printf("%d e' un numero primo\n", numero); else printf("%d non e' un numero primo\n", numero); }

/* Controllo se un numero è primo */ #include <iostream.h> #include <conio.h> int numero; //numero da analizzare (variabile globale) int divisore; //divisore trovato maggiore di 1 (globale) /* Procedura che individua il piu' piccolo divisore maggiore di 1 */ // dichiarazione e definizione della procedura divisoreMaggiore1() { int resto; //variabile locale divisore = 1; do divisore=divisore+1; resto = numero % divisore; } while(resto!=0); main() { cout<<"Immetti un numero intero positivo: "; cin>>numero; divisoreMaggiore1(); if(divisore==numero) cout<<numero<<" e' un numero primo"; else cout<<numero<<" non e' un numero primo"; }

La memoria dell’esempio Memoria globale Memoria main numero divisore Memoria divisoreMaggiore1 resto Ad ogni attivazione delle procedura viene allocata nuova memoria per i dati locali di questa. Al termine della procedura la memoria locale “scompare”.

Le funzioni Una funzione svolge, come la procedura, un compito ma, a differenza di questa, restituisce un valore Nella dichiarazione di una funzione è necessario specificare il tipo del valore ritornato Nella definizione è necessario utilizzare una specifica istruzione che fa terminare l’esecuzione della funzione e specifica il valore ritornato

Dichiarazione e definizione di funzione Pseudolinguaggio Funzione <NomeFunzione> Di Tipo <TipoRisultato> <istruzioni> Ritorna <Espressione> FineFunzione <NomeFunzione> Linguaggio C <tipoFunzione> <NomeFunzione> () { return <Espressione> }

Un esempio La funzione cubo di tipo intero restituisce il valore della variabile globale intera x elevato al cubo Pseudolinguaggio Funzione cubo Di Tipo Intero c Di Tipo Intero c  x * x * x Ritorna c FineFunzione cubo Linguaggio C int cubo () { int c; c = x * x * x; return c; }

Chiamata di funzione La chiamata di una funzione è sempre inserita in una espressione e provoca l’esecuzione della funzione e l’utilizzo del valore di ritorno Esempi: int potenza; potenza = cubo(); … printf(”%d al cubo vale %d”,x,cubo()); potenza = cubo() * x;

/* Uso della funzione cubo */ #include <stdio.h> int x; //variabile globale /* Funzione che restituisce il valore di x elevato al cubo */ // dichiarazione e definizione della funzione int cubo() { int c; c=x*x*x; return c; } main() printf("Immetti il valore: "); scanf("%d", &x); printf(”%d al cubo vale %d”,x,cubo());

Dichiarazione e definizione In linguaggio C è possibile separare le due fasi di dichiarazione e definizione di funzione Nella dichiarazione viene specificato solo il nome della funzione ed il suo tipo Nella definizione viene inoltre specificato il corpo della funzione La dichiarazione deve sempre precedere ogni chiamata della funzione

Indipendenza funzionale L’uso delle variabili globali vincola l’uso delle procedure e funzioni ad essere utilizzate in contesti particolari La funzione cubo presentata in precedenza restituisce il cubo della variabile x In uno stesso programma può risultare utile utilizzare la funzione per calcolare il cubo di differenti valori, in questo caso è necessario “spostare” questi valori nella variabile x prima di richiamare la funzione La funzione può essere utilizzata anche all’interno di un altro programma in cui potrebbe essere già presente una variabile x utilizzata per memorizzare dati di diverso tipo

I parametri I parametri permettono di rendere indipendente la procedura o la funzione dal contesto in cui viene inserita La procedura o funzione viene definita utilizzando i parametri formali Al momento dell’esecuzione vengono poi specificati i parametri attuali che vengono passati al sottoprogramma I parametri vengono specificati in fase di dichiarazione

Passaggio dei parametri per valore Al momento dell’esecuzione del sottoprogramma il valore dei parametri attuali viene assegnato ai parametri formali La sintassi della dichiarazione di procedura viene quindi ampliata per specificare i parametri. Possono essere presenti più parametri di vario tipo Pseudolinguaggio Procedura <NomeProcedura> (<par1> di Tipo <tipoPar1>,…) <istruzioni> <…> Fineprocedura <NomeProcedura> Linguaggio C <NomeProcedura> (<tipoPar1> <par1>, …) { }

Un esempio di procedura con parametri Procedura che visualizza i divisori di un numero intero void divisori(int n) //procedurra che visualizza i divisori di n { int divisore; //variabile locale - possibile divisore di n for (divisore=1;divisore<=n;divisore++) //per tutti i valori fra 2 e n-1 if (n%divisore==0) //se ho trovato un divisore cout<<divisore<<endl; //visualizza il divisore trovato } La procedura opera formalmente sul parametro n Al momento della chiamata viene specificato il valore del parametro attuale che viene assegnato al parametro formale divisori(10); //visualizza i divisori di 10 divisori(k); //visualizza i divisori di k // (k deve essere dichiarata come variabile int) divisori(k+2); //come parametro attuale è possibile utilizzare // una qualunque espressione di tipo int

Una funzione con due parametri /* Funzione che ritorna la potenza con base base ed esponente esp base : float base della potenza esp : int esponente (positivo) */ float potenza(float base, int esp) { float prod=1; //locale : per il calcolo della potenza for (int i=1;i<=esp;i++) // esp volte prod=prod*base; return prod; }

Esecuzione della funzione float b; //input valore che rappresenta la base int e; //input valore che rappresenta l'esponente cout<<"Inserire il valore della base "; cin>>b; cout<<"Inserire il valore dell'esponente "; cin>>e; cout<<b<<" elevato a "<<e<<" = "<<potenza(b,e)<<endl; cout<<"Il quadrato di "<<b<<" = "<<potenza(b,2)<<endl; cout<<"10 elevato a "<<e<<" = "<<potenza(10,e)<<endl; cout<<"Il cubo del doppio di "<<b<<" = "<<potenza(2*b,3)<<endl;