Programmazione I - Laboratorio



Похожие документы
Funzioni in C. Violetta Lonati

Corso di Analisi Matematica Serie numeriche

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

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

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

COGNOME E NOME (IN STAMPATELLO) MATRICOLA

La selezione binaria

Introduzione al MATLAB c Parte 2

I sistemi di numerazione

Gli array. Gli array. Gli array. Classi di memorizzazione per array. Inizializzazione esplicita degli array. Array e puntatori

LE FUNZIONI A DUE VARIABILI

Corso di Informatica

Università di Roma Tor Vergata Corso di Laurea triennale in Informatica Sistemi operativi e reti A.A Pietro Frasca.

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

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

Ricorsione. (da lucidi di Marco Benedetti)

Appunti sulla Macchina di Turing. Macchina di Turing

Studente (Cognome Nome): Corso di Informatica Corso di Laurea in Ingegneria Gestionale a.a Secondo Compitino 21 Dicembre 2006

Vettori Algoritmi elementari di ordinamento

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

La ricorsione. Politecnico di Milano Sede di Cremona

Ammortamento di un debito

Puntatori Passaggio di parametri per indirizzo

DI D AGRA R MM M I M A BLOCC C H C I TEORI R A E D D E SERC R I C ZI 1 1

Corso di Laurea in Ingegneria Gestionale Esame di Informatica a.a settembre 2011

2. Spiegare brevemente qual è la funzione del compilatore e la sua importanza per il programmatore.

Corso di Laurea Ingegneria Informatica Fondamenti di Informatica

Realizzazione di una classe con un associazione

Iniziamo con un esercizio sul massimo comun divisore: Esercizio 1. Sia d = G.C.D.(a, b), allora:

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

Matematica generale CTF

1 Serie di Taylor di una funzione

AA LA RICORSIONE

Informatica 3. Informatica 3. LEZIONE 10: Introduzione agli algoritmi e alle strutture dati. Lezione 10 - Modulo 1. Importanza delle strutture dati

Introduzione a Dev-C++

Laboratorio di Informatica

SAPIENZA Università di Roma Facoltà di Ingegneria dell Informazione, Informatica e Statistica

Algoritmo. I dati su cui opera un'istruzione sono forniti all'algoritmo dall'esterno oppure sono il risultato di istruzioni eseguite precedentemente.

Alcune regole di base per scrivere un programma in linguaggio C

LISTE, INSIEMI, ALBERI E RICORSIONE

RICORSIVITA. Vediamo come si programma la soluzione ricorsiva al problema precedente: Poniamo S 1 =1 S 2 =1+2 S 3 =1+2+3

Corso di Informatica Corso di Laurea in Ingegneria Gestionale a.a Secondo Compitino 17 Dicembre 2005

Funzioni. Il modello console. Interfaccia in modalità console

Crittografia. Primalità e Fattorizzazione. Corso di Laurea Specialistica. in Informatica

Nascita di Java. Che cos e Java? Caratteristiche di Java. Java: linguaggio a oggetti

u 1 u k che rappresenta formalmente la somma degli infiniti numeri (14.1), ordinati al crescere del loro indice. I numeri u k

Esempi di algoritmi. Lezione III

Proof. Dimostrazione per assurdo. Consideriamo l insieme complementare di P nell insieme

Allocazione dinamica della memoria - riepilogo

10 - Programmare con gli Array

void funzioneprova() { int x=2; cout<<"dentro la funzione x="<<x<<endl; }

Ricorsione. Corso di Fondamenti di Informatica

Corso di Laurea Ingegneria Informatica Fondamenti di Informatica 2

Lezione 8. La macchina universale

dall argomento argomento della malloc()

Concetto di Funzione e Procedura METODI in Java

Laboratorio di Calcolatori 1 Corso di Laurea in Fisica A.A. 2006/2007

E naturale chiedersi alcune cose sulla media campionaria x n

Politecnico di Milano Facoltà di Ingegneria Industriale INFORMATICA B

b i 1,1,1 1,1,1 0,1,2 0,3,4

Scopo della lezione. Informatica. Informatica - def. 1. Informatica

SISTEMI DI NUMERAZIONE IL SISTEMA DECIMALE

Le variabili. Olga Scotti

Nozione di algoritmo. Gabriella Trucco

13 - Gestione della Memoria nella Programmazione Orientata agli Oggetti

PREVENTIVO uno strumento che ci tutela!

Esercitazione 3. Corso di Fondamenti di Informatica

Introduzione alla programmazione in C

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

DAL PROBLEMA ALL'ALGORITMO AL PROGRAMMA SCRITTO IN Come. Scopo principale dell informatica è risolvere problemi con i calcolatori.

Funzioni funzione dominio codominio legge argomento variabile indipendente variabile dipendente

Esame di Informatica Generale 9 CFU 21 Giugno 2011 Professori: Carulli, Fiorino, Mazzei

Gestione della memoria. Paginazione Segmentazione Segmentazione con paginazione

SCHEDA DI RECUPERO SUI NUMERI RELATIVI

LINGUAGGI DI PROGRAMMAZIONE

Verifica della correttezza formale del numero di partita IVA

Arduino: Programmazione

3. La sintassi di Java

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

Fondamenti di Informatica 2

LABORATORIO DI PROGRAMMAZIONE EDIZIONE 1, TURNO B

Strutture di controllo del flusso di esecuzione

ALGEBRA DELLE PROPOSIZIONI

Matematica in laboratorio

Supermarket Progetto di Programmazione Febbraio 2010

Esercitazione Informatica I AA Nicola Paoletti

Laboratorio di Fondamenti di Informatica anno accademico Esercizi proposti il

Teoria dei Giochi. Dr. Giuseppe Rose Università degli Studi della Calabria Corso di Laurea Magistrale in Economia Applicata a.a 2011/2012 Handout 2

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

Introduzione al linguaggio C Gli array

Le funzioni in C. I programmi C sono costituiti da definizioni di variabili e funzioni.

4 3 4 = 4 x x x 10 0 aaa

Operatori logici e porte logiche

Per scrivere una procedura che non deve restituire nessun valore e deve solo contenere le informazioni per le modalità delle porte e controlli

Teoria in sintesi 10. Attività di sportello 1, 24 - Attività di sportello 2, 24 - Verifica conclusiva, 25. Teoria in sintesi 26

Транскрипт:

Programmazione I - Laboratorio Esercitazione 2 - Funzioni Gianluca Mezzetti 1 Paolo Milazzo 2 1. Dipartimento di Informatica, Università di Pisa http://www.di.unipi.it/ mezzetti mezzetti di.unipi.it 2. Dipartimento di Informatica, Università di Pisa http://www.di.unipi.it/ milazzo milazzo di.unipi.it Corso di Laurea in Informatica A.A. 2012/2013 G. Mezzetti & P. Milazzo (Univ. di Pisa) Esercitazione 2 A.A. 2012/2013 1 / 1

Dichiarazione e definizione di funzioni Le funzioni devono essere dichiarate e definite. La dichiarazione viene fatta all inizio ed ha questa forma: tipo - restituito nome -di - funzione ( parametri formali ); La definizione ha la forma tipo - restituito nome -di - funzione ( parametri formali ) dichiarazioni istruzioni provvedendo a far corrispondere i nomi della funzione e dei parametri formali. Esempio: int stupida ( int quanto, int perche ); int main (...)... int stupida ( int quanto, int perche )... Le funzioni possono stare solamente top-level (non si possono definire funzioni dentro funzioni)!! G. Mezzetti & P. Milazzo (Univ. di Pisa) Esercitazione 2 A.A. 2012/2013 2 / 1

Valore restituito Le funzioni possono restituire un valore attraverso il comando speciale return espressione. int stupida ( int quanto, int perche ) int val ; val = quanto / 2; return val ; Esiste un tipo speciale void per le funzioni che non restituiscono nulla. void stupidissima ( int quanto )... G. Mezzetti & P. Milazzo (Univ. di Pisa) Esercitazione 2 A.A. 2012/2013 3 / 1

Chiamata Una funzione viene chiamata usando il nome seguito dai parametri attuali tra parentesi, il numero ed il tipo dei parametri attuali deve corrispondere con quello dei parametri formali. int x = 10; stupida (x); I parametri attuali vengono accoppiati con i parametri formali (il modo dipende dal meccanismo di passaggio dei parametri) Quello che la funzione restituisce può essere ignorato o meno int x = 10; x = stupida (x); G. Mezzetti & P. Milazzo (Univ. di Pisa) Esercitazione 2 A.A. 2012/2013 4 / 1

Somma - somma.c /* Una funzione che somma due valori e restituisce il risultato */ # include < stdio.h> int somma ( int x, int y); int main ( void ) int a,b; a = 2; b = 3; return somma (a, b); int somma ( int x, int y) return x + y; Possiamo vedere il valore restituito dal main usando il comando echo $? G. Mezzetti & P. Milazzo (Univ. di Pisa) Esercitazione 2 A.A. 2012/2013 5 / 1

Passaggio di parametri - passaggiopervalore.c Il passaggio di parametri in C avviene per valore. /* Passaggio di parametri per valore */ # include < stdio.h> void fun ( int x); int main ( void ) int x = 5; fun (x); printf (" Dopo la chiamata x=%d \n",x); return 0; void fun ( int x) x =3; G. Mezzetti & P. Milazzo (Univ. di Pisa) Esercitazione 2 A.A. 2012/2013 6 / 1

Scoping - scoping.c L associazione tra i nomi e gli oggetti nell ambiente (scoping) in C viene detta lessicale o statica. Essa dipende solo dalla struttura del programma piuttosto e non dal suo comportamento a tempo di esecuzione. # include < stdio.h> int fun ( int x); int x =3; /* scope globale */ int main ( void ) int y=8,x =5; printf ("x dentro main %d \n",x); int x=3,y =4; printf ("x dentro un blocco %d \n",x); printf ("y dentro un blocco %d \n",y); int fun ( int x) /* int x =6; */ /* NO: Ri - dichiarazione di variabile nel blocco */ printf ("x dentro fun %d \n",x); /* printf ("y dentro fun %d \n",y);*/ /* NO: Scoping lessicale, y non si vede */ G. Mezzetti & P. Milazzo (Univ. di Pisa) Esercitazione 2 A.A. 2012/2013 7 / 1

Ricorsione Ogni funzione C può essere chiamata ricorsivamente La definizione matematica della successione di Fibonacci è ricorsiva: fib 0 = 0 fib 1 = 1 fib n = fib n 1 + fib n 2 if n > 1 G. Mezzetti & P. Milazzo (Univ. di Pisa) Esercitazione 2 A.A. 2012/2013 8 / 1

Fibonacci ricorsivo - fibonacciricorsivo.c /* Fibonacci ricorsivo */ # include < stdio.h> int fib ( int n); int main ( void ) printf (" Fibonacci 0 : %d\n",fib (0) ); printf (" Fibonacci 1 : %d\n",fib (1) ); printf (" Fibonacci 2 : %d\n",fib (2) ); printf (" Fibonacci 3 : %d\n",fib (3) ); printf (" Fibonacci 20 : %d\n",fib (20) ); printf (" Fibonacci 40 : %d\n",fib (40) ); printf (" Fibonacci 42 : %d\n",fib (42) ); return 0; int fib ( int n) if(n ==0) return 0; else if( n ==1) return 1; else return fib (n -1) + fib (n -2) ; G. Mezzetti & P. Milazzo (Univ. di Pisa) Esercitazione 2 A.A. 2012/2013 9 / 1

Quante chiamate? - fibonacciricorsivochiamate.c # include < stdio.h> int fib ( int n); /* ->*/ int chiamate =0; int main ( void ) printf (" Fibonacci 0:%d,1:%d,2:% d\n",fib (0),fib (1),fib (2) ); /* ->*/ chiamate =0; printf (" Fibonacci 20 : %d\n",fib (20) ); /* ->*/ printf (" Effettuate %d chiamate \n",chiamate ); chiamate =0; printf (" Fibonacci 40 : %d\n",fib (40) ); /* ->*/ printf (" Effettuate %d chiamate \n",chiamate ); chiamate =0; printf (" Fibonacci 42 : %d\n",fib (42) ); /* ->*/ printf (" Effettuate %d chiamate \n",chiamate ); return 0; int fib ( int n) /* ->*/ chiamate ++; if(n ==0) return 0; else if( n ==1) return 1; else return fib (n -1) + fib (n -2) ; G. Mezzetti & P. Milazzo (Univ. di Pisa) Esercitazione 2 A.A. 2012/2013 10 / 1

Ricorsione vs Iterazione L uso della ricorsione rende la stesura dei programmi più comprensibile e semplice ma è altrettanto semplice dare luogo a comportamenti non efficienti. Le chiamate a funzioni richiedono il mantenimento di una struttura dati aggiuntiva a runtime: i record di attivazione. Esiste un tipo di ricorsione che è equivalente all iterazione perché non richiede di memorizzare i record di attivazione: tail-recursion. I compilatori in alcuni casi riconoscono la tail-recursion ed ottimizzano il codice trasformando la ricorsione in iterazione. int tail ( int x)... return tail (...) ; G. Mezzetti & P. Milazzo (Univ. di Pisa) Esercitazione 2 A.A. 2012/2013 11 / 1

Fibonacci Ottimizzato e Tail Recursive Notiamo che prendendo serie di coppie consecutive di valori di Fibonacci: S 0 = (fib 0, fib 1 ) = (0, 1) S 1 = (fib 1, fib 0 + fib 1 ) = (1, 1) S 2 = (fib 2, fib 1 + fib 2 ) = (1, 2) S 3 = (fib 3, fib 2 + fib 3 ) = (2, 3) S 4 = (fib 4, fib 3 + fib 4 ) = (3, 6). S i = (fib i 1, fib i 2 + fib i 1 ) possiamo dare una nuova definizione di Fibonacci (tenendo conto che S i+1 si può calcolare da S i ) fib 0,Si = first(s i ) fib n,si = fib n 1,Si+1 tale che fib n = fib n,s0 G. Mezzetti & P. Milazzo (Univ. di Pisa) Esercitazione 2 A.A. 2012/2013 12 / 1

Fibonacci Ottimizzato e Tail Recursive - fibonaccitailrecursive.c /* Fibonacci tail - recursive */ # include < stdio.h> int fib ( int n); int fibt ( int n, int first, int second ); int main ( void ) printf (" Fibonacci 42 : %d\n",fib (42) ); return 0; int fib ( int n) return fibt (n,0,1) ; int fibt ( int n, int first, int second ) if(n ==0) return first ; else return fibt (n -1, second, first + second ); G. Mezzetti & P. Milazzo (Univ. di Pisa) Esercitazione 2 A.A. 2012/2013 13 / 1

Quante chiamate? - fibonaccitailrecursivechiamate.c # include < stdio.h> int fib ( int n); int fibt ( int n, int first, int second ); int chiamate =0; int main ( void ) printf (" Fibonacci 42 : %d\n",fib (42) ); printf (" Effettuate %d chiamate \n",chiamate ); return 0; int fib ( int n) return fibt (n,0,1) ; int fibt ( int n, int first, int second ) chiamate ++; if(n ==0) return first ; else return fibt (n -1, second, first + second ); G. Mezzetti & P. Milazzo (Univ. di Pisa) Esercitazione 2 A.A. 2012/2013 14 / 1

Radice quadrata Realizzare una funzione che calcoli la radice quadrata di un numero La radice quadrata di un numero x è compresa tra 0 e x Se (x/2) 2 > x allora la radice è tra 0 e x/2, altrimenti è tra x/2 e x Si può proseguire prendendo il punto centrale tra x/2 e x o 0 ed x/2 G. Mezzetti & P. Milazzo (Univ. di Pisa) Esercitazione 2 A.A. 2012/2013 15 / 1

Radice quadrata - radice.c I /* Una funzione che calcola la radice quadrata */ # include < math.h> /* for fabs () function */ # include < stdio.h> # define PRECISIONE 0.0001 float radice ( float x); float radicerc ( float x, float low, float hi); int main ( void ) printf ("La radice di 5 e %f",radice (2) ); return 0; float radice ( float x) if(x <=0) return -1; else return radicerc (x,0,x); float radicerc ( float x, float low, float hi) float mid ; mid = (hi+low ) /2.0; /* printf (" mid :%f \n", mid ); */ G. Mezzetti & P. Milazzo (Univ. di Pisa) Esercitazione 2 A.A. 2012/2013 16 / 1

Radice quadrata - radice.c II if( fabs ( mid * mid - x) < PRECISIONE ) return mid ; else if ( mid * mid - x > 0) return radicerc (x,low, mid ); else return radicerc (x,mid,hi); G. Mezzetti & P. Milazzo (Univ. di Pisa) Esercitazione 2 A.A. 2012/2013 17 / 1

Esercizio: massimo divisore comune Calcoliamo il massimo divisore comune (G.C.D.) tra due interi a e b positivi (> 0). L algoritmo di Euclide si basa sull osservazione che il G.C.D. tra due numeri divide anche la loro differenza (a = xm, b = xn allora a b = x(m n)). Quindi è possibile calcolare il G.C.D. tra due numeri calcolando quello tra uno di loro e la differenza tra i due. G. Mezzetti & P. Milazzo (Univ. di Pisa) Esercitazione 2 A.A. 2012/2013 18 / 1

Esercizio: massimo divisore comune Calcoliamo il massimo divisore comune (G.C.D.) tra due interi a e b positivi (> 0). L algoritmo di Euclide si basa sull osservazione che il G.C.D. tra due numeri divide anche la loro differenza (a = xm, b = xn allora a b = x(m n)). Quindi è possibile calcolare il G.C.D. tra due numeri calcolando quello tra uno di loro e la differenza tra i due. Suggerimento: gcd(a, a) = a gcd(a, b) = gcd(a, b a) gcd(a, b) = gcd(a b, b) if a < b if a > b G. Mezzetti & P. Milazzo (Univ. di Pisa) Esercitazione 2 A.A. 2012/2013 18 / 1

Esercizio: massimo divisore comune - gcd.c /* Massimo divisore comune */ # include < stdio.h> int gcd ( int a, int b); int main ( void ) printf (" GCD tra 5 e 10 e %d \n",gcd (5,10) ); printf (" GCD tra 30 e 35 e %d \n",gcd (30,35) ); printf (" GCD tra 13 e 17 e %d \n",gcd (13,17) ); printf (" GCD tra 20384572 e 356373848 e % d \ n", gcd (20384572,356373848) ); return 0; int gcd ( int a, int b) if(a==b) return a; else if( a < b) return else return gcd (a,b- a); gcd (a-b, b); G. Mezzetti & P. Milazzo (Univ. di Pisa) Esercitazione 2 A.A. 2012/2013 19 / 1

Esercizio: Funzione di Ackermann Definire la seguente funzione y se z = 0, x = 0 A(0, x 1, y) + 1 se z = 0, x 1 A(z, x, y) = 0 se z = 1, x = 0 1 se z 2, x = 0 A(z 1, A(z, x 1, y), y) se z 1, x 1 Il programma inoltre deve calcolare il numero di chiamate alla funzione A e stamparlo. G. Mezzetti & P. Milazzo (Univ. di Pisa) Esercitazione 2 A.A. 2012/2013 20 / 1

Esercizio: Funzione di Ackermann - ackermann.c I # include < stdio.h> int A( int z, int x, int y); int chiamate =0; int main ( void ) printf ("A (0,0,0) = %d\n",a (0,0,0) ); printf (" Effettuate %d chiamate \n",chiamate ); chiamate =0; printf ("A (0,3,4) = %d\n",a (0,3,4) ); /*A(0,x,y)=y+x*/ printf (" Effettuate %d chiamate \n",chiamate ); chiamate =0; printf ("A (1,3,4) = %d\n",a (1,3,4) ); /*A(1,x,y)=yx */ printf (" Effettuate %d chiamate \n",chiamate ); chiamate =0; printf ("A (2,3,4) = %d\n",a (2,3,4) ); /*A(2,x,y)=y^x*/ printf (" Effettuate %d chiamate \n",chiamate ); chiamate =0; printf ("A (3,3,4) = %d\n",a (3,3,4) ); /* 4^(4^4) */ printf (" Effettuate %d chiamate \n",chiamate ); chiamate =0; /* f(z,u, v) definisce una operazione binaria tra u e v al loro variare f( z+1,x, y) applica f(z,u, v) ad y x -1 volte. G. Mezzetti & P. Milazzo (Univ. di Pisa) Esercitazione 2 A.A. 2012/2013 21 / 1

Esercizio: Funzione di Ackermann - ackermann.c II cioe f(z,f(z+1,x -1,y),y) */ return 0; int A( int z, int x, int y) chiamate ++; if ( z ==0 && x ==0) return y; else if (z ==0 && x >=0) return A(0,x -1,y) +1; else if ( z ==1 && x ==0) return 0; else if (z >=2 && x ==0) return 1; else return A(z -1,A(z,x -1,y),y); G. Mezzetti & P. Milazzo (Univ. di Pisa) Esercitazione 2 A.A. 2012/2013 22 / 1

Esercizio: Probabilità di avere una buona giornata (meglio al PC) In Russia i biglietti degli autobus sono numerati con numeri a 6 cifre. Si dice che un russo possa augurarsi una buona giornata se quando sale sul bus la mattina possiede un biglietto in cui somma delle prima 3 cifre è la stessa delle ultime 3. Sviluppare un programma che calcoli la probabilità di avere una buona giornata Definire una funzione fortunato che verifica se un biglietto a 6 cifre è fortunato o meno. Contare il numero di biglietti fortunati totali e calcolare la probabilità (biglietti fortunati / biglietti totali) Calcolare la probabilità per biglietti da 2, 4, 6, 8, 10 cifre e concludere quindi quale sia il numero migliore di cifre perché i russi siano si sentano più fortunati. G. Mezzetti & P. Milazzo (Univ. di Pisa) Esercitazione 2 A.A. 2012/2013 23 / 1

/* Probabilita di avare una buona giornata */ # include <stdio.h> int fortunato ( int biglietto, int cifre ); int potenza ( int base, int exp ); int main () int i; int casi_possibili ; int casi_favorevoli ; float p; int cifre ; /* printf (" fortunato 123321 = % d\ n", fortunato (123321) ); */ for ( cifre =2; cifre <=10; cifre = cifre +2) casi_possibili = potenza (10, cifre ); casi_favorevoli =0; for ( i =0; i< casi_possibili ; i ++) if ( fortunato (i, cifre )) casi_favorevoli ++; /* ALTERNATIVA : casi_favorevoli = casi_favorevoli + fortunato (i); */ G. Mezzetti & P. Milazzo (Univ. di Pisa) Esercitazione 2 A.A. 2012/2013 24 / 1

p = (( float ) casi_favorevoli /( float ) casi_possibili ); printf (" Con %d cifre probabilita %6.3 f (%d casi su %d)\n", cifre,p, casi_favorevoli, casi_possibili ); int fortunato ( int biglietto, int cifre ) int i; int somma_prime, somma_ultime ; somma_ultime = 0; for (i =0; i< cifre /2; i ++) somma_ultime = somma_ultime + biglietto %10; biglietto = biglietto /10; somma_prime = 0; for (i =0; i< cifre /2; i ++) somma_prime = somma_prime + biglietto %10; biglietto = biglietto /10; return ( somma_ultime == somma_prime ); G. Mezzetti & P. Milazzo (Univ. di Pisa) Esercitazione 2 A.A. 2012/2013 25 / 1

int potenza ( int base, int exp ) int i; int risultato =1; for (i =0; i<exp ; i ++) risultato = risultato * base ; return risultato ; G. Mezzetti & P. Milazzo (Univ. di Pisa) Esercitazione 2 A.A. 2012/2013 26 / 1