Anno accademico 2010-2011 1 Le funzioni in C. Anno accademico 2010-2011 2 Sommario Le funzioniLe funzioni Il passaggio dei parametri Il passaggio dei.

Slides:



Advertisements
Presentazioni simili
Introduzione al linguaggio C++
Advertisements

INFORMATICA Altre Istruzioni di I/O
Il linguaggio C Le funzioni Ancora sull’ordinamento La funzione main()
LINGUAGGIO DI PROGRAMMAZIONE C
INFORMATICA Algoritmi fondamentali
LE FUNZIONI IN C Sommario 1 Introduzione 2 Moduli di programma in C
PUNTATORI Introduzione
Fondamenti di Informatica CDL in Ingegneria Gestionale (B)- A.A CDL in Ingegneria Gestionale (B)- A.A Programmazione Ricorsiva.
Introduzione al linguaggio C
Anno accademico Il preprocessore del linguaggio C.
Anno accademico Gli operatori e le espressioni in C.
Anno accademico Le classi di memorizzazione.
Fondamenti di Informatica I a.a Il linguaggio C Il preprocessore La sostituzione di macro Le compilazioni condizionali Linclusione di file C.
Anno accademico Array e puntatori in C.
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.
FUNZIONI DI BIBLIOTECA
Fondamenti di Informatica II Ingegneria Informatica / Automatica (A-I) Meccanica Prof. M.T. PAZIENZA a.a – 3° ciclo.
Argomenti dalla linea dei comandi Gli argomenti possono essere passati a qualsiasi funzione di un programma, compresa la main(), direttamente dalla linea.
Funzioni definite dall’utente
Tipi di dato e controllo del flusso Dott. Ing. Leonardo Rigutini Dipartimento Ingegneria dellInformazione Università di Siena Via Roma 56 – – SIENA.
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Corso di Fondamenti di programmazione a.a. 2009/2010 Prof.ssa Chiara Petrioli.
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE Puntatori Marco D. Santambrogio – Ver. aggiornata al 21 Marzo 2013.
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE Puntatori Marco D. Santambrogio – Ver. aggiornata al 4 Aprile 2013.
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE Stringhe e Puntatori Marco D. Santambrogio – Ver. aggiornata al 18 Marzo 2013.
Process synchronization
1 Corso di Laurea in Biotecnologie Informatica (Programmazione) Introduzione a JAVA Anno Accademico 2009/2010.
Il linguaggio Fortran 90: 4. Array: Vettori e Matrici
Fondamenti di Informatica I a.a Il linguaggio C Il controllo di flusso La selezione condizionale Listruzione switch I cicli Le istruzioni break,
Procedure e funzioni nei linguaggi di alto livello Lab Programmazione - turno /2006.
Istruzioni di selezione in Java Programmazione Corso di laurea in Informatica.
Approfondimento delle classi
memoria gestita staticamente:
Esercizi FUNZIONI Passaggio di parametri per valore, variabili e tipi locali e globali, prototipo.
Strutture di controllo in C -- Flow Chart --
Esercizi Puntatori, struct con campi puntatore, puntatori a struct, rapporto tra array e puntatori. FUNZIONI Passaggio di parametri per indirizzo, passaggio.
Dichiarazioni e tipi predefiniti nel linguaggio C
La Programmazione Ricorsiva
I File.
Le funzioni.
Espressioni condizionali
FUNZIONI: IL MODELLO APPLICATIVO 1) Valutazione, nellenvironment corrente, del simbolo che denota il nome della funzione; 2) Valutazione, nellenvironment.
FUNZIONI... Una funzione permette di dare un nome a una espressione rendendola parametrica float f(){ return * sin(0.75); } float f1(int x) { return.
2000 Prentice Hall, Inc. All rights reserved. Capitolo 6 (Deitel) I vettori Sommario Introduzione Vettori Dichiarazione di vettori 6.4.
CODIFICA Da flow-chart a C++.
2000 Prentice Hall, Inc. All rights reserved. Capitolo 10 (Deitel) Strutture, unioni ed enumerazioni Sommario Introduzione Definire le strutture.
Il linguaggio C Le funzioni C Language Il passaggio dei parametri
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Corso di Fondamenti di programmazione a.a. 2009/2010 Prof.ssa Chiara Petrioli.
Unità Didattica 3 Linguaggio C
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE Array e stringhe Marco D. Santambrogio – Ver. aggiornata al 9 Agosto 2013.
Fopndamenti di programmazione. 2 La classe String Una stringa è una sequenza di caratteri La classe String è utilizzata per memorizzare caratteri La classe.
1Piero Scotto - C14. Finalità del corso Programma Materiale Requisiti Spendibilità 2Piero Scotto - C14.
Sviluppare un programma in C che, dato un array da 100 elementi interi caricato con numeri casuali compresi tra [10,100], sia in grado di cercare il valore.
Complessità di un algoritmo
Anno accademico Le istruzioni di controllo in C.
CORSO DI PROGRAMMAZIONE II Lezione 22
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2006/2007 Corso di Programmazione 1 a.a.2006/2007 Prof.ssa Chiara Petrioli Corso di Laurea.
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE Puntatori Marco D. Santambrogio – Ver. aggiornata al 11 Ottobre 2014.
Fondamenti di Informatica 2 Ingegneria Informatica Docente: Giovanni Macchia a.a
Fondamenti di Informatica II Ingegneria Informatica (A-I) Prof. M.T. PAZIENZA a.a – 3° ciclo.
Sottoprogrammi e funzioni
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE Puntatori Marco D. Santambrogio – Ver. aggiornata al 11 Marzo 2014.
1 Il linguaggio C Precisazioni sull’esperienza in laboratorio.
Linguaggio C: Le basi Stefano Cagnoni e Monica Mordonini
Copyright © Istituto Italiano Edizioni Atlas
Il C `e un linguaggio di programmazione di uso generale, originariamente sviluppato per la scrittura del sistema operativo Unix, ed oggi disponibile su.
1 Metodo I metodi sono uno strumento che i programmatori usano per strutturare i programmi, sia per renderli più facili da capire che per permettere il.
Basi di Java Strutture base di Java. Basi di java ▪Variabili ▪Operatori ▪Condizioni e Cicli ▪Array.
10. Programmazione Ricorsiva Ing. Simona Colucci Informatica - CDL in Ingegneria Industriale- A.A
Linguaggio C: Funzioni e Puntatori Laboratorio di Programmazione Gruppo 1.
Transcript della presentazione:

Anno accademico Le funzioni in C

Anno accademico Sommario Le funzioniLe funzioni Il passaggio dei parametri Il passaggio dei parametri Le dichiarazioni e le chiamate Le dichiarazioni e le chiamate I prototipi di funzione I prototipi di funzione I puntatori a funzione I puntatori a funzione La ricorsione La ricorsione Ancora sullordinamentoAncora sullordinamento La funzione main()La funzione main()

Anno accademico Le funzioni

Anno accademico Gli argomenti di una funzione costituiscono il mezzo per passare dati al sottoprogramma per valore by valueIn C, gli argomenti sono passati per valore (by value), ovvero viene passata una copia dellargomento la funzione chiamata può modificare il valore della copia, ma non dellargomento originale parametro attuale parametro formaleLargomento passato viene detto parametro attuale, mentre la copia ricevuta è il parametro formale Nella chiamata per indirizzo, i parametri formale ed at- tuale fanno riferimento alla stessa area di memoria; nel caso di chiamata per valore, nel parametro formale va una copia del parametro attuale Indirizzo del parametro Parametro attuale Parametro formale Valore del parametro Passaggio per indirizzo Passaggio per valore Il passaggio dei parametri 1

Anno accademico Dato che in C gli argomenti vengono passati per valore, la funzione chiamata può modificare il parametro formale, senza che ciò si ripercuota sul parametro attuale printf() received_argf() a La funzione printf() non stam- pa 3, ma 2, in quanto il parametro formale received_arg in f() è una copia del parametro attuale a include main() { extern void f(); int a 2; f(a); /* passa una copia di a ad f() */ printf(%d\n, a); exit(0); } void f(received_arg) int received_arg; { received_arg 3; } Il passaggio dei parametri 2

Anno accademico In C, il parametro attuale, usato nella chiamata, ed il corrispondente parametro formale, usato nella definizione della funzione, vengono associati, indipendentemente dai nomi adottati Il primo parametro attuale viene a corrispondere al primo parametro formale, il secondo parametro attuale al secondo parametro formale, etc. È necessario che i tipi dei parametri attuali coincidano con quelli dei corrispondenti parametri formali Inoltre, se occorre che una funzione modifichi il valore di un oggetto, è necessario passare un puntatore alloggetto ed assegnare alloggetto un valore mediante loperatore di accesso allindirizzo contenuto nel puntatore Il passaggio dei parametri 3

Anno accademico void swap(x, y) int *x, *y; { register int temp; temp *y; *y *x; *x temp; } main() { int a 2, b 3; swap(&a, &b) printf(a %d\t b %d\n, a, b); } Esempio Nota: & scanf() scanf() scanf() Nota: Il passaggio degli argomenti per valore chiarisce la necessità di usare loperatore indirizzo di, &, nelle chiamate alla funzione scanf() : se venissero passate direttamente le variabili, scanf() non potrebbe mo- dificarle permanentemente; passando- ne gli indirizzi, scanf() può accede- re alle variabili ed assegnare i valori letti Lesecuzione del programma produce a 3b 2 a 3b 2 Il passaggio dei parametri 4

Anno accademico Le funzioni possono apparire in un programma in una delle tre forme seguenti: Definizione Definizione dichiarazione, che definisce il numero ed il tipo degli argomenti ed il comportamento della funzione Allusione a funzione prototipazione Allusione a funzione dichiarazione di una funzione definita altrove, che specifica la natura del valore restituito dalla funzione (con la prototipazione possono essere specificati anche il numero ed il tipo degli argomenti) Chiamata di funzione Chiamata di funzione invocazione di una funzione, che ha come effetto il trasferimento del controllo del programma alla funzione chiamata; al termine della funzione chiamata, lesecuzione riprende dallistruzione (del programma chiamante) immediatamente successiva alla chiamata completata Le dichiarazioni e le chiamate

Anno accademico È possibile specificare un nume- ro qualsiasi di argomenti intSe non altrimenti specificato, il tipo restituito si intende int voidSe la funzione non restituisce alcun valore, deve essere speci- ficato void come tipo restituito Dichiarazione argomento Tipo restituito ), Corpo funzione } ( Nome funzione { Argomento La sintassi della definizione di funzione

Anno accademico La dichiarazione degli argomenti segue le stesse regole delle dichiarazioni di variabili, con le seguenti eccezioni: register La sola classe di memorizzazione ammessa è register charshort int floatdoubleprototipazione Oggetti di tipo char e short sono convertiti in int, mentre oggetti di tipo float sono convertiti in double (con la prototipazione, le conversioni automatiche possono essere evitate) Un parametro formale dichiarato come array viene convertito in un puntatore ad un oggetto del tipo base dellarray Un parametro formale dichiarato di tipo funzione viene con- vertito in un puntatore a funzione In una dichiarazione, non può essere presente una inizializ- zazione intLa dichiarazione di un argomento può essere omessa: il tipo dellargomento è int per default La dichiarazione degli argomenti

Anno accademico returnLe funzioni possono restituire direttamente un solo valore, mediante listruzione return Il valore restituito può essere di tipo qualunque, eccetto array o funzione È possibile restituire indirettamente più di un valore mediante la restituzione di un puntatore ad un tipo composto Inoltre, una struttura o ununione possono essere restituite direttamente (anche se ciò è sconsigliato per motivi di efficienza) returnLa sintassi di unistruzione return è Espressione return I valori restituiti 1

Anno accademico returnIn una funzione può essere presente un numero qualsiasi di istruzioni return : la prima incontrata nellevolvere del flusso restituisce il controllo al programma chiamante Il valore restituito deve essere compatibile con il tipo della funzione return indefinitoSe non esiste alcuna istruzione return, il controllo del programma ritorna alla funzione chiamante quando si rag- giunge la parentesi graffa chiusa che conclude il corpo della funzione: il valore restituito è indefinito return voidUnistruzione return senza espressione può essere utilizzata (senza effetti collaterali) per restituire il controllo al chiaman- te dallinterno di una funzione dichiarata void I valori restituiti 2

Anno accademico Esempio: return floatEsempio: valori restituiti da return, implicitamente con- vertiti dal compilatore, per una funzione che dovrebbe restituire un float float f() { float f2; int a; char c; f2 a; /* OK, conversione implicita di a in float */ return a; /* OK, conversione implicita di a in float */ f2 c; /* OK, conversione implicita di c in float */ return c; /* OK, conversione implicita di c in float */ } I valori restituiti 3

Anno accademico Esempio: return charEsempio: istruzioni return corrette e scorrette nel caso di una funzione che restituisce un puntatore a char char *f() { char **cpp, *cp1, *cp2, ca[10]; int *ip1, *ip2; cp1 cp2 /* OK i tipi corrispondono */ return cp2; /* OK i tipi corrispondono */ cp1 *cpp; /* OK i tipi corrispondono */ return *cpp; /* OK i tipi corrispondono */ cp1 ca; /* OK i tipi corrispondono */ return ca; /* OK i tipi corrispondono, ma… */ cp1 *cp2; /* Errore: puntatore a char e char */ return *cp2; /* Errore: puntatore a char e char */ cp1 ip1; /* Errore: i tipi dei puntatori non corrispondono */ return ip1; /* Errore: i tipi dei puntatori non corrispondono */ return; /* provoca un comportamento indefinito */ /* dovrebbe restituire (char *) */ } I valori restituiti 4

Anno accademico Unallusione a funzione è una dichiarazione di una funzione definita altrove: serve principalmente per informare il compilatore sul tipo restituito dalla funzione intPoiché, se non specificato, il tipo di una funzione è int per default, le allusioni a funzioni intere potrebbero essere omesse È comunque buona norma inserire le allusioni a tutte le funzioni possibilità di determinare tutte le funzioni richiamate dalla lettura delle frasi dichiarative, senza dover scandire tutto il sorgente Per lo stesso motivo: omettere allusioni a funzioni non utilizzate, per evitare ambiguità Classe di memorizzazione Nome funzione Tipo restituito )( La sintassi dellallusione a funzione Le allusioni a funzione 1

Anno accademico externSe la classe di memorizzazione viene omessa, il compilatore assume la classe extern, corrispondente a una funzione la cui definizione può apparire nello stesso file sorgente o altrove staticLunica altra classe di memorizzazione ammessa è static, corrispondente ad una funzione definita nello stesso file Il tipo di funzione in unallusione deve coincidere con il tipo specificato nella definizione della funzione Le allusioni a funzione 2

Anno accademico Se la classe di memorizzazione ed il tipo vengono entrambi omessi, lespressione rappresenta una chiamata di funzione se appare allinterno di un blocco, unallusione se allesterno f1(); … … … main() { … … … f2(); … … … void Chiamata a funzione di tipo void int Allusione a funzione Il tipo di default è int Le allusioni a funzione 3

Anno accademico Le funzioni con allusioni allinterno di un blocco hanno ambito di visibilità a livello di blocco Le funzioni con allusioni allesterno di un blocco hanno ambito di visibilità a livello di file Le regole per la definizione della classe di memorizzazione sono diverse nel caso delle allusioni a funzione, rispetto agli altri tipi di variabili float func(); float *pfl, arfl[10]; auto Internamente ad un blocco le variabili sono auto, esternamente sono variabili globali extern Sia internamente che esternamente ad un blocco la funzione è extern per default Le allusioni a funzione 4

Anno accademico prototipi di funzioneI prototipi di funzione (introdotti nel C ) consentono di includere nelle allusioni la specifica del tipo degli argomenti Il compilatore può controllare che il tipo dei parametri attuali nelle chiamate di funzione sia compatibile con il tipo dei parametri formali specificati nellallusione Le conversioni automatiche non sono più necessarie (e non vengono effettuate) migliorando le prestazioni dei programmi che utilizzano pesantemente interi corti e floating point in singola precisione Esempi:Esempi: extern void func(int,float,char *); extern void func(int a,float b,char *pc); I due prototipi sono uguali: i nomi degli argomenti aumentano la leggibilità, ma non viene loro riservata memoria, né si creano conflitti con variabili omonime I prototipi di funzione 1

Anno accademico prototipazioneLa prototipazione assicura che venga passato il numero esatto di argomenti e impedisce il passaggio di argomenti che non possono essere convertiti implicitamente nel tipo corretto voidIn assenza di argomenti, occorre specificare il tipo void Se una funzione gestisce un numero di argomenti variabile, può essere utilizzata la forma … Esempio: printf()Esempio: il prototipo di printf() è: int printf(const char *format,…); che asserisce che il primo elemento è una stringa di caratteri costante, seguita da un numero non specificato di argomenti I prototipi di funzione 2

Anno accademico chiamata di funzioneinvocazione di funzioneUna chiamata di funzione, detta anche invocazione di funzione, trasferisce il controllo del programma alla funzione specificata Una chiamata di funzione è unespressione e può quindi comparire ovunque è ammessa unespressione voidSalvo il caso in cui il tipo restituito è void, il valore restituito dalla funzione viene sostituito alla chiamata Esempio: f()Esempio: se f() restituisce 1… ), ( Argomento Nome funzione a 1/3; a f()/3; Le chiamate di funzione 1

Anno accademico voidI valori di ritorno vengono ignorati solo quando la funzione restituisce void voidSe si desidera ignorare deliberatamente un valore restituito, è buona norma convertirlo esplicitamente in void printf()scanf() printf() scanf()Questa regola è stata trasgredita ogni volta che sono state usate le funzioni printf() e scanf(), che restituiscono valori interi (in particolare lintero restituito da printf() e scanf() è il numero di oggetti scritti/letti) f(); (void) f(); Le chiamate di funzione 2

Anno accademico int int float doubleIn mancanza di prototipazione, tutti gli argomenti scalari di dimensioni minori di un int vengono convertiti in int e gli argomenti float vengono convertiti in double char shortfloat intdoubleSe il parametro formale è dichiarato essere un char o uno short o un float, anche la funzione chiamata, che si aspetta di ricevere int o double, rispettivamente, riconverte ai tipi più corti char short float Ogni volta che viene passato come parametro un char, uno short o un float vengono effettuate due conversioni, nel programma chiamante e nella funzione chiamata Le conversioni automatiche degli argomenti 1

Anno accademico Nellipotesi di coincidenza fra i tipi dei parametri formali ed attuali, gli argomenti vengo- no passati correttamente Tuttavia… le conversioni au- tomatiche possono far dimi- nuire lefficienza del pro- gramma La prototipazione evita le conversioni automatiche de- gli argomenti { char a; short b; float c; foo(a,b,c); /* a e b vengono convertiti in interi * c viene convertito in double */ … … … } foo(x,y,z) char x; /* Largomento ricevuto è convertito da int a char */ short y; /* Largomento ricevuto è convertito da int a short */ float z; /* Largomento ricevuto è convertito da double a float */ { … … … } Esempio Le conversioni automatiche degli argomenti 2

Anno accademico Nellallusione extern int f(); f puntatore a funzione f il simbolo f è un puntatore a funzione, che permette di accedere alla locazione riferita dal puntatore; dato che f è un puntatore costante, non è possibile assegnargli un valore Per dichiarare un puntatore variabile a funzione, è necessario far precedere il nome del puntatore da un asterisco Esempio:Esempio: int (*pf)(); /* dichiara un puntatore ad una funzione intera */ *pf puntatore ad int Le parentesi che delimitano *pf sono necessarie per consentire un raggruppamento corretto: se non venissero specificate si otterrebbe la dichiarazione di una funzione che restituisce un puntatore ad int I puntatori a funzione

Anno accademico Per disporre dellindirizzo di una funzione è sufficiente specificare il nome di funzione, omettendo lelenco degli argomenti tra parentesi Se vengono specificate le parentesi, si ottiene una chiamata di funzione pf f1(); /* SCORRETTO: f1 restituisce un int mentre pf è un puntatore */ pf &f1(); /* SCORRETTO: non si può accedere allindirizzo del risultato di una funzione */ pf &f1; /* SCORRETTO: &f1 è un puntatore a puntatore pf è un puntatore a funzione intera */ { extern int f1(); int (*pf) (); /* dichiara pf come un puntatore ad una funzione che restituisce un int */ pf f1; /* assegna lindirizzo di f1 a pf */ … … … Lassegnamento di valori ai puntatori a funzione

Anno accademico Corrispondenza obbligatoria int intCorrispondenza obbligatoria: se viene dichiarato un puntatore a una funzione che restituisce un int, a tale puntatore è possibile assegnare solo lindirizzo di una funzione che restituisce un int Se non vi è corrispondenza di tipo, si ha una segnalazione di errore in compilazione extern int if1(),if2(),(*pif)(); extern float ff1(),(*pff)(); extern char cf1(),(*pcf)(); main () { pif if1; pif cf1; /* SCORRETTO: i tipi non corrispondono */ pff if2; /* SCORRETTO: i tipi non corrispondono */ pcf cf1; if1 if2; /* SCORRETTO: assegnamento a costante */ } La concordanza fra tipi

Anno accademico Per accedere allindirizzo contenuto in un puntatore a funzione e richiamare la funzione corrispondente… …deve essere utilizzata la stessa sintassi della dichiarazione del puntatore a funzione… …con laggiunta delle parentesi tonde e della lista degli argomenti { extern int f1(); int (*pf)(); int a, answer; pf f1; answer (*pf)(a); /* richiama la funzione f1 con argomento a */ … … … La chiamata di funzioni mediante puntatori 1

Anno accademico Per laccesso allindirizzo contenuto in un puntatore a funzione può essere utilizzato un numero qualsiasi di asterischi perché… Un nome di funzione è convertito in un puntatore alla funzione ****pf pf * Le parentesi modificano lordine di valutazione facendo sì che si valuti per prima lespressione ****pf : ogni accesso allindirizzo contenuto in pf provoca nuovamente la sua trasformazione in un puntatore, poiché lelenco degli argomenti non viene considerato; ciò avviene solo quando il compilatore ha analizzato tutti gli operatori *, trasformando lespressione in una chiamata di funzione pf(a); (*pf)(a); La chiamata di funzioni mediante puntatori 2 (****pf)(a); (*pf)(a);

Anno accademico void bubble_sort(list, list_size) int list[], list_size; { int j, temp, sorted FALSE; while (!sorted) { sorted TRUE; /* assume list ordinato */ for (j 0; j < list_size 1; j ) { if (list[j] > list[j 1]) { /* almeno un elemento non in ordine */ sorted FALSE; temp list[j]; list[j] list[j 1]; list[j 1] temp; } } /* fine del ciclo for */ } /* fine del ciclo while */ } Problema :Problema : ordinare un array di interi, con possibilità di scelta fra ordinamento crescente e decrescente I puntatori a funzione sono impiegati come meccanismo per gestire operazioni simili, evitando la duplicazione di codice compare() È lunica istruzione che deve essere modificata: loperatore relazionale distin- gue i due casi Invece di riscrivere il programma, è più semplice estrarre lespressione, racchiudendola in una fun- zione compare() if(compare(list[j],list[j 1])) Una funzione di ordinamento 1 30

Anno accademico compare() list[j]list[j 1]Se lordinamento è crescente, compare() deve restituire 1 quando list[j] è maggiore di list[j 1], 0 nel caso contrario; se lordinamento e decrescente i valori di ritorno sono invertiti Le funzioni di confronto sono due: compare() bubble_sort()Per scegliere fra le due funzioni, occorre trasformare compare() in un puntatore a funzione, in grado di attivare le due funzioni in maniera selettiva, ed aggiungere un argomento a bubble_sort() per indicare il tipo di ordinamento prescelto int compare_descend(a,b) int a, b; /* Confronta a,b restituendo 1 se a<b */ { return a<b; } int compare_ascend(a,b) int a, b; /* Confronta a,b restituendo 1 se a>b */ { return a>b; } Una funzione di ordinamento 2

Anno accademico define FALSE 0 define TRUE 1 void bubble_sort(list, list_size, compare ) int list[], list_size, (*compare)(); { int j, temp, sorted FALSE; while (!sorted) { sorted TRUE; /* assume list ordinato */ for (j 0; j < list_size 1; j ) { if ((*compare)(list[j], list[j 1])) { /* almeno un elemento non in ordine */ sorted FALSE; temp list[j]; list[j] list[j 1]; list[j 1] temp; } } /* fine del ciclo for */ } /* fine del ciclo while */ } 32 define ASCEND compare_ascend define DESCEND compare_descend extern void bubble_sort(); extern int compare_ascend(); extern int compare_descend(); include include sort.h main( ) { static int list[] {1,0,5,444, 332, 76}; define LIST_SIZE (sizeof(list)/sizeof(list[0])) bubble_sort(list, LIST_SIZE, DESCEND); exit(0); } File header sort.h Funzione bubble_sort() Programma principale Una funzione di ordinamento 3

Anno accademico ricorsivaUna funzione è ricorsiva se richiama se stessa Nei programmi ricorsivi, è necessario prevedere una condizione di terminazione, altrimenti il programma non si interrompe void recurse() { static count 1; printf(%d\n, count); count ; recurse(); } main( ) { extern void recurse(); recurse(); } count count count La funzione stampa il valore di count (che è 1, inizialmente), incrementa count ed infine richiama se stessa; la seconda volta count vale 2… il procedimento viene ripetuto allinfinito … Infine, il calcolatore esaurirà la memoria disponibile per lo stack ed il programma verrà interrotto (con segnalazione di errore) La ricorsione 1

Anno accademico condizione baseLa condizione che conclude la ricor- sione è detta condizione base count countSe count avesse durata automatica anziché fissa, il programma non terminerebbe mai perché, ad ogni nuova chiamata, count verrebbe re inizializzata ad 1 Nella ricorsione, ad ogni nuova chiamata di funzione, il compilatore crea un nuovo insieme completo di variabili automatiche che, pur avendo lo stesso nome, occupano aree di memoria distinte (sullo stack) void recurse() { static count 1; if (count > 3) return; else { printf(%d\n,count); count ; recurse(); } main( ) { extern void recurse(); recurse(); } La ricorsione 2

Anno accademico Luso di variabili fisse è una delle modalità di controllo della ricorsione, laltra è luso di valori dingressoLuso di variabili fisse è una delle modalità di controllo della ricorsione, laltra è luso di valori dingresso Esempio:Esempio: Calcolo della somma degli interi da 1 ad n int sum(n) int n; { if (n < 1) return n; else return(n sum(n 1)); } Il valore restituito da chiamate ricorsive 5 sum(4) 3 sum(2) sum(5) 4 sum(3) 2 sum(1)

Anno accademico )Fattoriale int rfatt(n) int n; { if (n 0) return 1; else return (n rfatt(n 1)); } Funzione ricorsiva Funzione ricorsiva int fatt(n) int n; { int t, result; result 1; for (t 2; t< n; t ) result t; return result; } Funzione non ricorsiva Esempi di funzioni ricorsive 1

Anno accademico )I numeri di Fibonacci Si consideri la sequenza di numeri interi 0,1,1,2,3,5,8,13,21… nota come successione di Fibonacci La legge di generazione della successione è espressa mediante la relazione di ricorrenza F 0 0F 1 1 F n F n 1 F n 2 Nota:legge di Fibonacci Nota: La legge di Fibonacci (Leonardo Pisano, detto il Fibonacci, Pisa 1170) descrive la crescita del numero di coppie di conigli a partire da una singola coppia, supponendo che ogni coppia procrei, ogni mese, una nuova coppia di conigli, che sia in grado di riprodursi a partire dal mese successivo Esempi di funzioni ricorsive 2

Anno accademico Calcolo delln esimo termine della successione di Fibonacci int fibonacci (int n); main (void) { int numero; printf(\nInserisci il numero dordine del termine ); scanf(%d, &numero); printf(L%d esimo numero di Fibonacci è %d,numero,fibonacci(numero)); } int fibonacci(n) int n; { if (n < 0) return 0; /* passo base: n 0 */ else if (n 1) return 1; /* passo base: n 1 */ else return (fibonacci(n 1) + fibonacci(n 2)); /* passo di induzione */ } fibonacci() Prototipo della funzione fibonacci() Esempi di funzioni ricorsive 3

Anno accademico )Algoritmo di Euclide per il calcolo del M.C.D. int mcd(int m, int n); main (void) { int numero1, numero2; printf(Inserisci i due numeri ); scanf(%d %d, &numero1, &numero2); printf(Il MCD tra %d e %d è %d\n,numero1,numero2,mcd(numero1,numero2)); } int mcd(m, n) int m, n; { if (m 0) return n; /* caso m 0 */ else if ((n 0) || (m n)) return m; /* caso n 0 o m n */ else if (m > n) return mcd(n, m%n); /* caso m>n */ else return mcd(m, n%m); /* caso m<n */ } mcd() Prototipo della funzione mcd() Esempi di funzioni ricorsive 4

Anno accademico Come si seleziona lelemento perno? 4)Quicksort Esempi di funzioni ricorsive 5

Anno accademico void qsort (int v[], int left, int right); { /* ordina v[left]…v[right] in ordine crescente */ int i, last; extern void swap(int v[], int i, int j); if (left > right) /* se il vettore ha meno di due elementi */ return; /* si esce dalla funzione */ /* sposta lelemento discriminante in v[left] */ swap(v, left, (left right)/2); last left; for (i left 1; i < right; i ) /* suddivide */ if (v[i]<v[left]) swap(v, last, i); /* ripristina lelemento discriminante */ swap(v, left, last); qsort(v, left, last 1); qsort(v, last 1, right); } Sceglie lelemento mediano come perno Quicksort Esempi di funzioni ricorsive 6 void swap(int v[],int i,int j); { /* scambia v[i] e v[j] */ int temp; if (i j) return; temp v[i]; v[i] v[j]; v[j] temp; }

Anno accademico Quicksort fornisce le prestazioni migliori quando la disposizione dei dati è tale che, ad ogni passo, lelemento perno viene collocato alla metà esatta dellinsieme da ordinare Sia n 2 h 1 Ad ogni passo gli elementi separatori dei sottoinsiemi individuati vengono collocati al centro del sottoinsieme corrispondente Il numero dei confronti ad ogni passo è proporzionale ad n e, in questo caso, i passi sono esattamente h 1 Quicksort, nel caso ottimo, ha complessità dellordine di O (nlog 2 n) Quicksort, nel caso ottimo, ha complessità dellordine di O (nlog 2 n) Si può dimostrare che tale è anche la complessità nel caso medio: statisticamente, le configurazioni non ordinate dellinsieme sono preponderanti Tuttavia, quando il vettore è già ordinato, occorrono n passi, il che fa scadere la complessità del Quicksort a O (n 2 )Tuttavia, quando il vettore è già ordinato, occorrono n passi, il che fa scadere la complessità del Quicksort a O (n 2 ) Esempi di funzioni ricorsive 7

Anno accademico )Mergesort Esempi di funzioni ricorsive 8

Anno accademico Lordinamento per fusione, Mergesort, è un metodo vantaggioso perché comporta un numero di confronti che è sempre dello stesso ordine, qualsiasi sia la configurazione iniziale del vettore da ordinare Mergesort opera, ad ogni passo, partizioni dellinsieme di partenza che hanno la stessa dimensione Per n 2 h, il numero di passi eseguiti dallalgoritmo è h e, ad ogni passo, vengono effettuati O (n) confronti La complessità dellalgoritmo è sempre dellordine di O (nlog 2 n)La complessità dellalgoritmo è sempre dellordine di O (nlog 2 n) Esempi di funzioni ricorsive 9

Anno accademico define MAX_DIM 100 void merge(int *v,int b1,int b2,int ei) { int i, j, k, w[MAX_DIM]; i b1; j b2; k b1; /* inizializzazione */ while ((i<b2) && (j<1 ei)) if (v[i]<v[j]) w[k ] v[i ]; else w[k ] v[j ]; if (i<=b2) do w[k ] v[i ]; while (i ! b2); else do w[k ] v[j ]; while (j ! 1 ei); for (i b1; i< ei; i ) v[i] w[i]; } 45 Mergesort Esempi di funzioni ricorsive 10 void mergesort (int *v, int i, int j) { /* ordina v con indici tra i e j */ int k; if (((i 1) j) && (v[i]>v[j])) swap(v, i, j); /* passo base */ if ((i 1)<j) /* passo di induzione */ { k (i j)/2; mergesort(v, i, k); mergesort(v, k 1, j); merge(v,i,k 1,j); }

Anno accademico main()Tutti i programmi C devono contenere una funzione, il main(), che è la prima eseguita allinterno di un programma e la cui conclusione determina la fine del programma main()Il compilatore gestisce main() come le altre funzioni, con leccezione che, al momento dellesecuzione, lambiente deve fornire due argomenti: argc int argc, è un int che rappresenta il numero di argomenti presenti sulla linea di comando allatto dellinvocazione del comando argv array di puntatori argv, è un array di puntatori agli argomenti della linea di comando La funzione main() 1

Anno accademico argv[0]Un puntatore al comando stesso è memorizzato in argv[0] : nellesempio, è stato utilizzato loperatore di incremento prefisso per non visualizzare il comando UNIX echoNei sistemi UNIX esiste un programma simile, detto echo, che visualizza gli argomenti della linea di comando main (argc, argv) int argc; char *argv[]; { /* visualizza gli argomenti della * linea di comando */ while ( argc > 0) printf(%s, * argv); printf(\n); exit(0); } Quando viene eseguito un programma, gli argomenti della linea di comando devono essere separati da uno o più caratteri di spaziatura La funzione main() 2

Anno accademico main()Gli argomenti della linea di comando sono sempre passati a main() come stringhe di caratteri Se rappresentano valori nu- merici, devono essere conver- titi esplicitamente atoi() int atof() float Esistono le apposite funzioni della libreria di run time: atoi() converte una stringa in int, atof() converte una stringa in float, etc. include main (argc, argv) int argc; char *argv[]; { float x, y; if (argc < 3) { printf(Uso: power \n); printf(Restituisce arg1 alla arg2\n); return; } x atof(* argv); y atof(* argv); printf(%f\n, pow(x, y)); } La funzione main() 3