1 Funzioni e Procedure in C Corso di Informatica A Vito Perrone
Copyright © The McGraw-Hill Companies, srl 2 Funzioni e Procedure in C Informatica A – V. Perrone Indice Motivazioni Il concetto di sottoprogramma Struttura completa di un programma C Le funzioni –Esecuzione delle funzioni e passaggio dei parametri Le procedure Il passaggio dei parametri per indirizzo Aspetti avanzati nelluso dei sottoprogrammi
Copyright © The McGraw-Hill Companies, srl 3 Funzioni e Procedure in C Informatica A – V. Perrone Motivazioni Riusabilità (scrivere una sola volta del codice usato più volte) Astrazione (esprimere in modo sintetico operazioni complesse) Due tipi di sottoprogrammi –Funzioni –Procedure
Copyright © The McGraw-Hill Companies, srl 4 Funzioni e Procedure in C Informatica A – V. Perrone Motivazioni: un esempio #define MaxNumMov typedef struct { int giorno; int mese; int anno; } Data; typedef struct { char causale[100]; Data data; float importo; } Movimento; typedef struct { int numMovimenti; Movimento dati[MaxNumMov]; } ElencoMovimenti; ElencoMovimenti entrate; ElencoMovimenti uscite; float saldo; Come calcolare il totale delle entrare e delle uscite?
Copyright © The McGraw-Hill Companies, srl 5 Funzioni e Procedure in C Informatica A – V. Perrone Motivazioni: un esempio POSSIBILE SOLUZIONE …. int i; float totEntrate, totUscite; totEntrate = 0; for(i=0; i<entrate.numMovimenti; i++) { totEntrate += entrate.dati[i].importo; } totUscite = 0; for(i=0; i<uscite.numMovimenti; i++) { totUscite += uscite.dati[i].importo; } saldo = totEntrate – totUscite; ….
Copyright © The McGraw-Hill Companies, srl 6 Funzioni e Procedure in C Informatica A – V. Perrone Motivazioni: un esempio Ma ci piacerebbe di più scrivere: saldo = tot(entrate) – tot(uscite); mettendo a fattor comune il codice simile Ma per fare questo dobbiamo definire un sottoprogramma che calcola tot –Si tratta di un programma asservito al programma principale Il sottoprogramma deve essere prima di tutto definito e poi può essere invocato (chiamato)
Copyright © The McGraw-Hill Companies, srl 7 Funzioni e Procedure in C Informatica A – V. Perrone Struttura di un programma C direttive; parte dichiarativa globale contiene la dichiarazione di tutti gli elementi che sono condivisi dal programma principale e dai sottoprogrammi. main definizioni di sottoprogrammi funzioni o procedure, a seguire il programma principale. Il main è un -particolare- sottoprogramma tra gli altri il main e ciascun sottoprogramma possono usare tutti e soli gli elementi che sono stati dichiarati nella loro propria parte dichiarativa, nonché quelli che sono stati dichiarati nella parte dichiarativa globale
Copyright © The McGraw-Hill Companies, srl 8 Funzioni e Procedure in C Informatica A – V. Perrone Funzioni (1) Definizione (semplificata) di una funzione: testata (header); due parti, racchiuse fra parentesi graffe: la parte dichiarativa (detta parte dichiarativa locale); la parte esecutiva (detta corpo della funzione). La testata contiene: –tipo del risultato, –identificatore del sottoprogramma, –lista dei parametri -formali- cui la funzione viene applicata con il relativo tipo; –(dominio e codominio della funzione) –Ogni parametro formale è un identificatore di tipo seguito da un identificatore. –Una funzione non può restituire array o funzioni ma può restituire un puntatore a qualsiasi tipo.
Copyright © The McGraw-Hill Companies, srl 9 Funzioni e Procedure in C Informatica A – V. Perrone Funzioni (2) int FatturatoTotale(ElencoFatture par) boolean Precede(StringaCaratteri par1, StringaCaratteri par2) boolean Esiste(int par1, SequenzaInteri par2) /* Stabilisce se il primo parametro, di tipo intero, appartiene all'insieme di interi contenuti nel secondo parametro: una sequenza di interi */ MatriceReali10Per10 *MatriceInversa(MatriceReali10Per10 *par)
Copyright © The McGraw-Hill Companies, srl 10 Funzioni e Procedure in C Informatica A – V. Perrone Funzioni (3) intFatturatoTotale (ElencoFatture parametro) { intTotale, Cont; Totale = 0; for (Cont = 0; Cont < parametro.NumFatture; Cont++) Totale = Totale + parametro.Sequenza[Cont].Importo; return Totale; }
Copyright © The McGraw-Hill Companies, srl 11 Funzioni e Procedure in C Informatica A – V. Perrone Funzioni (4) intRadiceIntera (int par) { intcont; cont = 0; while (cont*cont <= par) cont = cont + 1; return (cont – 1); }
Copyright © The McGraw-Hill Companies, srl 12 Funzioni e Procedure in C Informatica A – V. Perrone Chiamata delle funzioni x = sin(y) – cos(PiGreco – alfa); x = cos(atan(y) – beta); x = sin(alfa); y = cos(alfa) – sin(beta); z = sin(PiGreco) + sin(gamma); RisultatoGestione =FatturatoTotale(ArchivioFatture) – SommaCosti(ArchivioCosti); Det1 = Determinante(Matrice1); Det2 = Determinante(MatriceInversa(Matrice2)); TotaleAssoluto = Sommatoria(Lista1) + Sommatoria(Lista2); ElencoOrdinato = Ordinamento(Elenco); OrdinatiAlfabeticamente = Precede(nome1, nome2);
Copyright © The McGraw-Hill Companies, srl 13 Funzioni e Procedure in C Informatica A – V. Perrone Allinterno 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 (prototipo) si limita a richiamarne la testata. Utile quando la chiamata di una funzione precede, nel codice, la definizione della funzione, oppure le funzioni utilizzate da un programma sono definite in file propri del sistema C (e.g., le funzioni di libreria). Aiuta il compilatore ed è buono stile di programmazione Prototipo delle funzioni
Copyright © The McGraw-Hill Companies, srl 14 Funzioni e Procedure in C Informatica A – V. Perrone Esecuzione delle funzioni e passaggio dei parametri (1) /* Programma Contabilità (1) */ /* Parte direttiva */ #include #defineMaxNumFatture1000 /* Parte dichiarativa globale */ typedef charString [30]; typedef struct{StringIndirizzo; intAmmontare; DataDataFattura; }DescrizioneFatture; typedef struct{intNumFatture; DescrizioneFattureSequenza[MaxNumFatture]; }ElencoFatture;
Copyright © The McGraw-Hill Companies, srl 15 Funzioni e Procedure in C Informatica A – V. Perrone /* Programma Contabilità (2)*/ main() { ElencoFattureArchivioFatture1, ArchivioFatture2; intFatt1, Fatt2, Fatt; intFatturatoTotale(ElencoFatture parametro); /* Prototipo della funzione FatturatoTotale */.... Fatt1 = FatturatoTotale(ArchivioFatture1); Fatt2 = FatturatoTotale(ArchivioFatture2); Fatt = Fatt1 + Fatt2;.... } /* Fine del main del programma Contabilità */ Esecuzione delle funzioni e passaggio dei parametri (2)
Copyright © The McGraw-Hill Companies, srl 16 Funzioni e Procedure in C Informatica A – V. Perrone /* Definizione della funzione FatturatoTotale */ int FatturatoTotale (ElencoFatture parametro) { intTotale, Cont;.... return Totale; } Esecuzione delle funzioni e passaggio dei parametri (3)
Copyright © The McGraw-Hill Companies, srl 17 Funzioni e Procedure in C Informatica A – V. Perrone Ambienti di esecuzione, macchine astratte master e slave ArchivioFatture1 ArchivioFatture2 Fatt1 Fatt2 Parametro Totale Cont FatturatoTotale
Copyright © The McGraw-Hill Companies, srl 18 Funzioni e Procedure in C Informatica A – V. Perrone Esecuzione delle funzioni e passaggio dei parametri (4) x = sin(atan(y) – acos(z)); Equivale a : temp1 = atan(y); temp2 = acos(z); temp3 = temp1 – temp2 x = sin(temp3);
Copyright © The McGraw-Hill Companies, srl 19 Funzioni e Procedure in C Informatica A – V. Perrone Procedure (1) typedef enum {VerdeSinistra, VerdeDestra} TipoStato; typedef struct{TipoStatoStato; intCodaSinistra; intCodaDestra; } TipoSemaforo; TipoSemaforoSemaforo; AggiornaSemaforo : Diminuisce di un valore costante il campo CodaSinistra o CodaDestra a seconda che lo stato del semaforo sia VerdeSinistra o VerdeDestra ; Legge dal terminale i valori NuoviArriviSinistri e NuoviArriviDestri e li somma, rispettivamente, a CodaSinistra e CodaDestra ; Dà al campo Stato il valore VerdeSinistra se CodaSinistra > Coda Destra e viceversa.
Copyright © The McGraw-Hill Companies, srl 20 Funzioni e Procedure in C Informatica A – V. Perrone Procedure (2) /*Programma Contabilità (1)*/ #include #defineMaxNumFatture typedef struct{Stringindirizzo; intammontare; DataDataFattura; } DescrizioneFatture; typedef struct{intNumFatture; DescrizioneFattureSequenza[MaxNumFatture]; } ElencoFatture; ElencoFattureArchivioFatture;
Copyright © The McGraw-Hill Companies, srl 21 Funzioni e Procedure in C Informatica A – V. Perrone /*Programma Contabilità (2)*/ main() { DataDataOdierna; DescrizioneFattureFattura1, Fattura2; voidInserisciFattura(DescrizioneFatture Fattura); booleanPrecede(DataNum1, DataNum2); /*Stabilisce se Num1 precede Num2*/ … /* Sequenza di istruzioni che leggono i datidi una fattura in Fattura1 */ InserisciFattura(Fattura1);... /* Sequenza di istruzioni che leggono i dati di una fattura in Fattura2 */ if(Precede(Fattura2.DataEmissione, DataOdierna)) InserisciFattura(Fattura2);... } Procedure (3)
Copyright © The McGraw-Hill Companies, srl 22 Funzioni e Procedure in C Informatica A – V. Perrone /*Programma Contabilità (3)*/ voidInserisciFattura(DescrizioneFatture Fattura) { if(ArchivioFatture.NumFatture == MaxNumFatture) printf("L'archivio è pieno.\n"); else { ArchivioFatture.NumFatture = ArchivioFatture.NumFatture + 1; ArchivioFatture.Sequenza[ArchivioFatture.NumFatture–1] = Fattura; } Procedure (4)
Copyright © The McGraw-Hill Companies, srl 23 Funzioni e Procedure in C Informatica A – V. Perrone Ambiente globale ArchivioFatture Ambiente locale di InserisciFattura Ambiente di main di Programma Contabilità DataOdierna Fattura Fattura1 Fattura2... Esecuzione delle procedure
Copyright © The McGraw-Hill Companies, srl 24 Funzioni e Procedure in C Informatica A – V. Perrone Passaggio parametri per indirizzo (1) voidInserisciFattura(DescrizioneFattureFattura, ElencoFatture ArchivioFatture) /*In questa versione della procedura, sia la fattura da inserire sia l'archivio in cui inserirla sono dei parametri */ { if(ArchivioFatture.NumFatture == MaxNumFatture) printf("L'archivio è pieno."); else { ArchivioFatture.NumFatture = ArchivioFatture.NumFatture + 1; ArchivioFatture.Sequenza[ArchivioFatture.NumFatture–1] = Fattura; } /*Fine della procedura InserisciFattura */ InserisciFattura (Fattura1, ArchivioFatture5);Non funziona! Perché?
Copyright © The McGraw-Hill Companies, srl 25 Funzioni e Procedure in C Informatica A – V. Perrone Ind(x) = 2034 Parametri attualiParametri formali Passaggio per valore 243 Ind(y) = 1004 Passaggio per indirizzo yA Passaggio parametri per indirizzo (2)
Copyright © The McGraw-Hill Companies, srl 26 Funzioni e Procedure in C Informatica A – V. Perrone In C la modalità di passaggio dei parametri a un sottoprogramma è sempre quella di passaggio per valore. Per simulare il passsaggio per indirizzo: utilizzare il costruttore puntatore per la definizione dei parametri formali della funzione; usare loperatore di dereferenziazione di puntatore (operatore * o –> ) allinterno del corpo della funzione; passare al momento della chiamata della funzione come parametro attuale un indirizzo di variabile (usando loperatore & ). Passaggio parametri per indirizzo (3)
Copyright © The McGraw-Hill Companies, srl 27 Funzioni e Procedure in C Informatica A – V. Perrone /*Programma Contabilità (1)*/... main() { ElencoFattureArchivioFatture5; /* Qui ArchivioFatture5 è una variabile locale del main. */ DataDataOdierna; DescrizioneFattureFattura1, Fattura2; voidInserisciFattura (DescrizioneFattureFattura, ElencoFatture *PointToArchivioFatture); /* Prototipo della procedura InserisciFattura */ BooleanPrecede(Data Num1, DataNum2); /* Prototipo della funzione Precede */ Passaggio parametri per indirizzo (4)
Copyright © The McGraw-Hill Companies, srl 28 Funzioni e Procedure in C Informatica A – V. Perrone /*Programma Contabilità (2)*/... /* Sequenza di istruzioni che leggono i dati di una fattura in Fattura1 */ InserisciFattura(Fattura1, &ArchivioFatture5); /* Chiamata della procedura InserisciFattura: alla procedura viene passato il valore di Fattura1 e l'indirizzo di ArchivioFatture5 */... /* Sequenza di istruzioni che leggono i dati di una fattura in Fattura2 */ if(Precede(Fattura2.DataEmissione, DataOdierna) InserisciFattura(Fattura2,&ArchivioFatture5); /* Nuova chiamata della procedura InserisciFattura: alla procedura viene passato il valore di Fattura2 e -nuovamente- l'indirizzo di Archivio Fatture5 (ma potrebbe essere un altro) */... } Passaggio parametri per indirizzo (5)
Copyright © The McGraw-Hill Companies, srl 29 Funzioni e Procedure in C Informatica A – V. Perrone /*Programma Contabilità (3)*/... /* Definizione della procedura InserisciFattura */ voidInserisciFattura(DescrizioneFatture Fattura, ElencoFatture*PointToArchivioFatture); /* In questa versione della procedura, la fattura da inserire e l'indirizzo dell'archivio in cui inserirla sono dei parametri */ { if(PointToArchivioFatture–>NumFatture == MaxNumFatture) /* PointToArchivioFatture è una variabile che punta a una struttura avente un campo di nome NumFatture */ printf("L'archivio è pieno.\n"); else { PointToArchivioFatture–>NumFatture = PointToArchivioFatture–>NumFatture +1; PointToArchivioFatture–>Sequenza[PointToArchivioFatture–>NumFatture – 1] = Fattura; } Passaggio parametri per indirizzo (6)
Copyright © The McGraw-Hill Companies, srl 30 Funzioni e Procedure in C Informatica A – V. Perrone Aspetti avanzati
Copyright © The McGraw-Hill Companies, srl 31 Funzioni e Procedure in C Informatica A – V. Perrone I blocchi Un blocco è composto da due parti racchiuse tra parentesi graffe: una parte dichiarativa (facoltativa); una sequenza di istruzioni. Diversi blocchi possono comparire internamente al main o alle funzioni che compongono un programma C. I blocchi possono risultare paralleli o annidati
Copyright © The McGraw-Hill Companies, srl 32 Funzioni e Procedure in C Informatica A – V. Perrone /* Programma ComplessoInStruttura */ #include /* Parte dichiarativa globale */ intg1, g2; charg3; intf1(intpar1, intpar2);... main () { inta, b; intf2(intpar3, intpar1);... /* blocco1 */ { chara, c;... /* blocco2 annidato nel blocco1 */ { floata;... } /* Fine blocco2 */ } /* Fine blocco1 */ } /* Fine main */
Copyright © The McGraw-Hill Companies, srl 33 Funzioni e Procedure in C Informatica A – V. Perrone intf1(intpar1, intpar2) { intd;... /* blocco3 */ { inte;... } /* Fine blocco3 */ /* blocco4 */ { intd;... } /* Fine blocco4 */ } /* Fine f1 */
Copyright © The McGraw-Hill Companies, srl 34 Funzioni e Procedure in C Informatica A – V. Perrone /* Definizione della funzione f2 */ intf2(intpar3, intpar4) { intf;... } /* Fine f2 */
Copyright © The McGraw-Hill Companies, srl 35 Funzioni e Procedure in C Informatica A – V. Perrone
Copyright © The McGraw-Hill Companies, srl 36 Funzioni e Procedure in C Informatica A – V. Perrone La durata delle variabili variabili fisse o statiche ( static ): i loro valori vengono mantenuti anche allesterno del loro ambito di visibilità. variabili automatiche ( auto ): i loro valori non vengono mantenuti allesterno del proprio ambito di visibilità. Sono variabili fisse le variabili globali del programma
Copyright © The McGraw-Hill Companies, srl 37 Funzioni e Procedure in C Informatica A – V. Perrone /* Definizione della funzione f1 */ intf1(intpar1, intpar2) { static intd; /* blocco3 */ {inte;... } /*Fine blocco3 */ /* blocco4 */ {intd;... } /* Fine blocco4 */ } /* Fine f1 */
Copyright © The McGraw-Hill Companies, srl 38 Funzioni e Procedure in C Informatica A – V. Perrone Parametri di tipo array (1) Lindirizzo di base dellarray viene passato per valore alla funzione. typedefdoubleTipoArray[MaxNumElem] Le tre testate di funzione riportate di seguito sono equivalenti: doublesum(TipoArraya, intn) /* n è la dimensione dell'array passato */ doublesum(double*a, intn) doublesum(doublea[ ], intn)
Copyright © The McGraw-Hill Companies, srl 39 Funzioni e Procedure in C Informatica A – V. Perrone Parametri di tipo array (2) doublemul(doublea[ ], intn) /* n è la dimensione dell'array passato */ { inti; doubleris; ris = 1.0; for (i=0; i < n; i=i+1) ris = ris * a[i]; return ris; } v array di 50 elementi: ChiamataValore calcolato e restituito mul(v, 50)v[0]*v[1]*... *v[49] mul(v, 30)v[0]*v[1]*... *v[29] mul(&v[5], 7)v[5]*v[6]*... *v[11] mul(v+5, 7)v[5]*v[6]*... *v[11]
Copyright © The McGraw-Hill Companies, srl 40 Funzioni e Procedure in C Informatica A – V. Perrone Parametri di tipo struttura Una struttura può essere passata per valore anche quando contiene un componente di tipo array.
Copyright © The McGraw-Hill Companies, srl 41 Funzioni e Procedure in C Informatica A – V. Perrone Effetti collaterali (1) int x ; /* Variabile globale */ intPrimoEsempio(intpar) { return(par + x) } Nel corso del seguente frammento di programma: x = 1; x = PrimoEsempio(1); La sua chiamata produce, la prima volta, il risultato 2, la seconda volta 3.
Copyright © The McGraw-Hill Companies, srl 42 Funzioni e Procedure in C Informatica A – V. Perrone intSecondoEsempio(int*par) { *par = *par + 1; return*par; } y = SecondoEsempio(&z); Assegna alla variabile y il valore di z+1, ma anche z assume lo stesso valore. effetto collaterale (side effect) Effetti collaterali (2)
Copyright © The McGraw-Hill Companies, srl 43 Funzioni e Procedure in C Informatica A – V. Perrone int x ; /* Variabile globale */ intTerzoEsempio(intpar) { x = par + 2; return(par + 1); } Altro effetto collaterale: z = TerzoEsempio(4); Assegna a z il valore 5, ma anche il valore 6 a x. A Effetti collaterali (3)
Copyright © The McGraw-Hill Companies, srl 44 Funzioni e Procedure in C Informatica A – V. Perrone DescrizioneFatture EsaminaElimina(Giorno ParGiorno) { DescrizioneFattureFatturaLocale; FatturaLocale = ArchivioFatture.Sequenza[ArchivioFatture.NumFatture – 1]; if(FatturaLocale.DataEmissione.Giorno == ParGiorno) ArchivioFatture.NumFatture = ArchivioFatture.NumFatture – 1; return FatturaLocale; } Effetti collaterali (4)
Copyright © The McGraw-Hill Companies, srl 45 Funzioni e Procedure in C Informatica A – V. Perrone Uso interscambiabile di procedure e funzioni intf(intpar1) {... returnrisultato; } Essa può essere trasformata nella procedura seguente: voidf(intpar1, int*par2) {... *par2 = risultato; } Successivamente, una chiamata come: y = f(x); verrà trasformata in: f(x, &y);
Copyright © The McGraw-Hill Companies, srl 46 Funzioni e Procedure in C Informatica A – V. Perrone La standard library del C Sottoprogrammi di largo uso predefiniti: –Matematica –I/O –Grafica Librerie di sottoprogrammi: –Predefinite –Costruite dai programmatori applicativi Però luso di librerie diminuisce la portabilità A meno che anche le librerie (almeno le fondamentali) non siano standardizzate La grande forza del C: la libreria standard
Copyright © The McGraw-Hill Companies, srl 47 Funzioni e Procedure in C Informatica A – V. Perrone #include /* Programma Concatenazione di stringhe */ #include #define LunghezzaArray 50 main() { charPrimaStringa[LunghezzaArray], SecondaStringa[LunghezzaArray], StringaConc[2 * LunghezzaArray]; unsignedLunghezzaConc; scanf(%s, PrimaStringa); scanf(%s, SecondaStringa); if(strcmp(PrimaStringa, SecondaStringa) <= 0) { strcpy(StringaConc, PrimaStringa); strcat(StringaConc, SecondaStringa); } else { strcpy(StringaConc, SecondaStringa); strcat(StringaConc, PrimaStringa); } LunghezzaConc = strlen(StringaConc); printf(La stringa ottenuta concatenando le due stringhe lette è %s. Essa è lunga %d caratteri\n, StringaConc, LunghezzaConc); }
Copyright © The McGraw-Hill Companies, srl 48 Funzioni e Procedure in C Informatica A – V. Perrone I file header Le funzioni della libreria sono disponibili in C come file di codice compilato. È compito del programmatore inserire nel programma i prototipi delle funzioni che verranno usate La libreria C comprende alcuni file, chiamati header file, che contengono i prototipi di un insieme di funzioni di libreria. #include e altre #include Il preprocessore copia il contenuto del file stdio.h nel programma, inserendo i prototipi delle funzioni che appartengono al gruppo di cui xxx.h è il file testata.