Funzioni e sviluppo top - down costruire programmi modificando programmi esistenti funzioni di libreria sviluppo top-down e diagrammi di struttura funzioni senza argomenti funzioni con argomenti 1
Costruire programmi modificando programmi esistenti è spesso possibile riutilizzare parti di codice preesistenti nella costruzione di nuovi programmi Esempio: calcolare l area e la circonferenza di un cerchio calcolare il peso di un insieme di rondelle 2
Area e circonferenza di un cerchio Problema: dato il raggio di un cerchio, calcolarne l area e la circonferenza Analisi: l input del problema è il raggio del cerchio; ci sono due output: area e circonferenza; il raggio può essere un numero reale, quindi utilizzo variabili di tipo double; mi occorrono le relazioni geometriche tra raggio e area di un cerchio e tra raggio e circonferenza 3
Analisi - richieste sui dati Costanti del problema PI = 3.14159 Dati in input double radius /* raggio del cerchio */ Dati in output double area /* area del cerchio */ double circum /* circonferenzza del cerchio */ Formule utilizzate 2 area =! radius circumference = 2! radius 4
Progettazione Algoritmo iniziale 1. prendi il raggio 2. calcola l area 3. calcola la circonferenza 4. visualizza area e circonferenza Raffinamenti dell algoritmo Raffinamento del passo 2 2.1 assegna PI * radius * radius ad area Raffinamento del passo 3 3.1 assegna 2 * PI * radius a circum 5
Fase di implementazione nelle fasi di analisi e progettazione ho prodotto la seguente documentazione: descrizione delle richieste sui dati (fase di analisi) algoritmo che risolve il problema (fase di progettazione) utilizzo queste informazioni come punto di partenza per la produzione del codice: trasformo le richieste sui dati in definizioni di costanti e dichiarazioni di variabili utilizzo i passi dell algoritmo e i raffinamenti come commenti scrivo il codice C corrispondente sotto ogni (sotto)passo non raffinato 6
/* * Calcola area e circonferenza di un cerchio */ #include <stdio.h> #define PI 3.14159 int main(void) { double radius; /* input - raggio del cerchio */ double area; /* output - area del cerchio */ double circum; /* output - circonferenza del cerchio */ /* prendi il raggio */ /* calcola l area */ /* assegna PI * radius * radius ad area */ /* calcola la circonferenza */ /* assegna 2 * PI * radius a circum */ /* visualizza area e circonferenza */ } return (0); 7
/* * Calcola area e circonferenza di un cerchio */ #include <stdio.h> #define PI 3.14159 int main(void) { double radius; /* input - raggio del cerchio */ double area; /* output - area del cerchio */ double circum; /* output - circonferenza del cerchio */ /* prendi il raggio */ printf("inserisci il raggio> "); scanf("%lf", &radius); /* calcola l area */ area = PI * radius * radius; 8
/* calcola la circonferenza */ circum = 2 * PI * radius; /* visualizza area e circonferenza */ printf("area = %.4f\n", area); printf("circonferenza = %.4f\n", circum); } return (0); 9
Test utilizzare un raggio per il quale sia semplice calcolare a mano l area e la circonferenza Inserisci il raggio> 5.0 Area = 78.5397 Circonferenza = 31.4159 10
Calcolare il peso totale di un insieme di rondelle esempio di utilizzo della soluzione di un problema per risolvere un problema più complesso Problema Un azienda produttrice di rondelle deve stimare i costi di spedizione. Scrivere un programma che calcola il peso di una quantità specificata di rondelle. 11
Analisi Per calcolare il peso di una rondella devo conoscere l area, lo spessore e la densità del materiale utilizzato; spessore e densità sono dati di input; l area del bordo della rondella si calcola a partire da due dati forniti in input: il diametro interno e il diametro esterno; utilizzo come dati intermedi il raggio interno ed esterno, l area del bordo della rondella e il peso di una singola rondella. Per fornire in output il peso complessivo dovrò conoscere la quantità di rondelle. 12
Analisi - richieste sui dati Costanti del problema PI = 3.14159 Dati in input double hole_diameter /* diametro del buco */ double edge_diameter /* diametro esterno */ double thickness /* spessore della rondella */ double density /* densita del materiale */ double quantity /* numero di rondelle */ Dati in output double weight /* peso totale */ 13
Analisi - richieste sui dati Variabili del programma double hole_radius /* raggio del buco */ double edge_radius /* raggio esterno */ double rim_area /* area del bordo */ doble unit_weight /* peso di 1 rondella */ Formule utilizzate 2 area del cerchio =! raggio raggio del cerchio = diametro /2 area del bordo = area cerchio esterno - area cerchio interno peso unitario = area del bordo spessore densità 14
Progettazione Algoritmo iniziale 1. prendi diametro interno, diametro esterno e spessore di una rondella 2. prendi densità del materiale e quantità di rondelle 3. calcola l area del bordo della rondella 4. calcola il peso di una rondella 5. calcola il peso totale 6. visualizza il peso totale 15
Progettazione Raffinamento passo3 3.1 calcola hole_radius e edge_radius 3.2 rim_area è PI * edge_radius * edge_radius - PI * hole_radius * hole_radius Raffinamento passo 4 4.1 unit_weight è rim_area * thickness * density 16
/* * Calcola il peso di una quantita specificata di rondelle. */ #include <stdio.h> #define PI 3.14159 int main(void) { double hole_diameter; /* input - diametro del buco */ double edge_diameter; /* input - diametro esterno */ double thickness; /* input - spessore della rondella */ double density; /* input - densita del materiale */ double quantity; /* input - numero di rondelle */ double weight; /* output - peso totale */ double hole_radius; /* raggio del buco */ double edge_radius; /* raggio esterno */ double rim_area; /* area del bordo */ double unit_weight; /* peso di una rondella */ 17
/* Prendi diametro interno, diametro esterno e spessore di una rondella.*/ printf("inner diameter in centimeters> "); scanf("%lf", &hole_diameter); printf("outer diameter in centimeters> "); scanf("%lf", &edge_diameter); printf("thickness in centimeters> "); scanf("%lf", &thickness); /* Prendi densita del materiale e quantita di rondelle. */ printf("material density in grams per cubic centimeter> "); scanf("%lf", &density); printf("quantity in batch> "); scanf("%lf", &quantity); /* Calcola l area del bordo della rondella */ hole_radius = hole_diameter / 2.0; edge_radius = edge_diameter / 2.0; rim_area = PI * edge_radius * edge_radius - PI * hole_radius * hole_radius; 18
/* Calcola il peso di una rondella. */ unit_weight = rim_area * thickness * density; /* Calcola il peso totale. */ weight = unit_weight * quantity; /* Visualizza il peso totale. */ printf("\nthe expected weight of the batch is %.2f", weight); printf(" grams.\n"); } return (0); 19
Test utilizzare dati per i quali è sempice verificare la correttezza del risultato (es. diametro interno = 2 e diametro esterno = 4 forniscono un area del bordo = 3!) prima verificare il calcolo del peso unitario (quantità = 1) verificare quindi il calcolo del peso totale (quantità = 1000) 20
Esempio di test Inner diameter in centimeters> 2 Outer diameter in centimeters> 4 Thickness in centimeters> 1 Material density in grams per cubic centimeter> 1 Quantity in batch> 1000 The expected weight of the batch is 9424.78 grams. 21
Esercizio Le rondelle vengono ricavate da lastre di materiale di forma rettangolare e di spessore uniforme. Scrivere un programma che calcola 2 la quantità di materiale (in cm ) necessaria per fabbricare una data quantità di rondelle; il peso del materiale di scarto. 22
Funzioni predefinite Riutilizzo di codice obiettivo: produrre codice senza errori riutilizzo di parti di codice già scritte e testate il C fornisce librerie di funzioni predefinite che permettono, ad esempio, di effettuare calcoli matematici 23
Esempio: radice quadrata chiamata a funzione y = sqrt(x); nome della funzione parametro La chiamata a funzione attiva il codice della funzione sqrt, passando il contenuto della variabile x come argomento. Al termine dell esecuzione della funzione, il risultato della funzione è sostituito al posto della chiamata. 24
Esempio x y 16.0?? y = sqrt(x); x y 16.0 4.0 1. x contiene 16.0, quindi sqrt calcola 16.0, che è 4.0 2. il risultato della funzione, 4.0, viene assegnato a y 25
Black box Una funzione può essere vista come una scatola nera : fornendogli uno o più valori in input, questa ritorna automaticamente un valore in output y = sqrt(x); 16.0 calcolo della radice quadrata il risultato è 4.0 26
Esempio w z 9.0?? z = 5.7 + sqrt(w); w z 9.0 8.7 1. w contiene 9.0, quindi sqrt calcola 9.0, che è 3.0 2. i valori 5.7 e 3.0 vengono sommati 2. il risultato della della somma, 8.7, viene assegnato a z 27
/* * Performs three square root computations */ #include <stdio.h> /* definitions of printf, scanf */ #include <math.h> /* definition of sqrt */ int main(void) { double first, second, /* input - two data values */ first_sqrt, /* output - square root of first */ second_sqrt, /* output - square root of second */ sum_sqrt; /* output - square root of sum */ /* Get first number and display its square root. */ printf("enter the first number> "); scanf("%lf", &first); first_sqrt = sqrt(first); printf("the square root of the first number is %.2f\n", first_sqrt); 28
/* Get second number and display its square root. */ printf("enter the second number> "); scanf("%lf", &second); second_sqrt = sqrt(second); printf("the square root of the second number is %.2f\n", second_sqrt); /* Display the square root of the sum of the two numbers. */ sum_sqrt = sqrt(first + second); printf("the square root of the sum is %.2f\n", sum_sqrt); } return (0); 29
Test Enter the first number> 9.0 The square root of the first number is 3.00 Enter the second number> 16.0 The square root of the second number is 4.00 The square root of the sum is 5.00 Note il programma effettua tre chiamate alla funzione sqrt;nell ultima chiamata, l argomento della funzione è un espressione. ogni istruzione è una chiamata a una funzione di libreria; ho utilizzato le funzioni predefinite del C come blocchi per la costruzione del programma 30
Funzioni di libreria abs(x) ritorna il valore assoluto dell argomento (di tipo int) standard header file: <stdlib.h> argomento: int risultato: int Es: abs(-5) è 5 abs(2) è 2 31
Funzioni di libreria Se una funzione di libreria viene chiamata con un argomento di tipo diverso da quello richiesto, l argomento viene convertito nel tipo richiesto prima di essere usato. La conversione da double a int provoca una perdita di informazione. Es: abs(-4.36) è 4 Per calcolare il valore assoluto di numeri reali bisogna utilizzare la funzione fabs 32
Funzioni di libreria fabs(x) ritorna il valore assoluto dell argomento (di tipo double) standard header file: <math.h> argomento: double risultato: double Es: fabs(-5.348) è 5.348 fabs(203) è 203.0 33
Funzioni di libreria in <math.h> cos(x) sin(x) tan(x) coseno dell angolo x seno dell angolo x tangente dell angolo x argomento: double (in radianti) risultato: double Es: cos(0.0) è 1.0 34
Funzioni di libreria in <math.h> x exp(x) e (e = 2.718...) log(x) logaritmo naturale di x (per x > 0.0) log10(x) logaritmo in base 10 di x (per x > 0.0) sqrt(x) radice quadrata di x (per x " 0.0) argomento: double risultato: double Es: log10(100.0) è 2.0 35
Funzioni di libreria in <math.h> pow(x,y) argomenti: double risultato: double ritorna x y se x è negativo, y deve essere intero (non deve avere cifre decimali) Es.: pow(9.0, 0.5) è 3.0 pow(4.0, -1.0) è 0.25 pow(-2.0, 2.0) è 4.0 pow(-2.0, 3.0) è -8.0 36
Funzioni di libreria in <math.h> ceil(x) il più piccolo valore intero (senza decimali) non minore di x floor(x) il più grande valore intero (senza decimali) non maggiore di x argomento: double risultato: double Es.: floor(45.23) è 45.0 ceil(45.23) è 46.0 ceil(-45.23) è -45.0 37
Esempio 2 Calcolare le radici dell equazione ax + bx + c = 0 quando il discriminante è positivo root = 1 - b + b - 4ac 2a 2 root = 2 - b - b - 4ac 2a 2 38
/* Compute two roots, root_1 and root_2, for disc > 0.0 */ disc = pow(b, 2) - 4 * a * c; root_1 = (-b + sqrt(disc)) / (2 * a); root_2 = (-b - sqrt(disc)) / (2 * a); 39
Funzione definite dall utente Supponiamo di aver definito le funzioni find_area(r) ritorna l area di un cerchio di raggio r find_circum(r) ritorna la circonferenza di un cerchio di raggio r queste funzioni possono essere utilizzate direttamente nei programmi per il calcolo di area e circonferenza e per il calcolo del peso delle rondelle, rendendo tali programmi più chiari e leggibili 40
... rim_area = PI * edge_radius * edge_radius - PI * hole_radius * hole_radius;... può essere sostituita da... rim_area = find_area(edge_radius) - find_area(hole_radius);... 41
Sviluppo top - down metodo per la soluzione di problemi: il problema viene suddiviso in sottoproblemi ogni sottoproblema viene risolto le soluzioni ai sottoproblemi vengono combinate per ottenere la soluzione al problema iniziale Diagramma della struttura strumento di documentazione che evidenzia le relazioni tra il problema e i sottoproblemi 42
Esempio: disegnare semplici figure Problema: disegnare sullo schermo figure del tipo seguente: / \ / \ / \ ------- ------- *** * * *** / \ / \ / \ ------- / \ / \ / \ 43
Analisi: La casa è formata da un triangolo senza base sopra ad un rettangolo. La figura stilizzata è costituita da un cerchio, un triangolo e un triangolo senza base. Entrambe le figure possono essere disegnate a partire dalle seguenti componenti: un cerchio una linea orizzontale due linee parallele due linee che si intersecano 44
Progettazione (figura stilizzata): Algoritmo iniziale 1. disegna un cerchio 2. disegna un triangolo 3. disegna due linee che si intersecano Raffinamento del passo 2 2.1 disegna due linee che si intersecano 2.2 disegna una linea orizzontale 45
Diagramma della struttura problema originario disegna una figura sottoproblemi 1 livello disegna un cerchio disegna un triangolo disegna linee intersecanti sottoproblemi 2 livello disegna linee intersecanti disegna linea orizzontale 46
Nota i sottoproblemi appaiono sia nell algoritmo che nel diagramma di struttura; l algoritmo specifica l ordine in cui vengono eseguiti i sottoproblemi; il diagramma di struttura specifica le relazioni tra problema originario e sottoproblemi 47
Funzioni senza argomenti prototipo di funzione definizione di funzione disposizione delle funzioni nel programma ordine di esecuzione delle funzioni e del main vantaggi derivati dall uso di funzioni visualizzazione di istruzioni per l utente 48
Funzioni senza argomenti Le funzioni definite dall utente permettono di implementare facilmente gli algoritmi sviluppati con metodo top-down: per ogni sottoproblema, viene definita una funzione che lo implementa. Il tipo più semplice di funzione non ha argomenti e non ritorna valori. 49
/* * Draws a stick figure */ #include <stdio.h> /* function prototypes */ void draw_circle(void); /* Draws a circle */ void draw_intersect(void); /* Draws intersecting lines */ void draw_base(void); /* Draws a base line */ void draw_triangle(void); /* Draws a triangle */ 50
int main(void) { /* Draw a circle. */ draw_circle(); /* Draw a triangle. */ draw_triangle(); /* Draw intersecting lines. */ draw_intersect(); } return (0); 51
Istruzione di chiamata a funzione (funzioni senza argomenti e valore di ritorno) Sintassi fname(); Esempi draw_circle(); Viene invocata la funzione fname. Quando fname ha terminato l esecuzione, l esecuzione procede con l istruzione che segue la chiamata a fname. Le parentesi dopo fname indicano che si tratta di una funzione che non richiede argomenti. 52
Prototipi di funzione Come gli altri identificatori, una funzione deve essere dichiarata prima dell uso. Una funzione può essere dichiarata inserendo un prototipo di funzione prima della funzione main. Il prototipo comunica al compilatore: il tipo di dato della funzione il nome della funzione informazioni sugli argomenti della funzione 53
Prototipo di funzione (funzione senza argomenti) sintassi ftype fname(void); esempi void draw_circle(void); L identificatore fname è il nome della funzione. ftype specifica il tipo di dato del risultato della funzione. ftype è void se la funzione non ritorna un valore. La lista di argomenti (void) indica che la funzione non ha argomenti. Il prototipo di funzione deve apparire prima della prima chiamata alla funzione. 54
Definizione di funzione il prototipo specifica gli argomenti della funzione e il valore ritornato; le operazioni effettuate dalla funzione sono specificate nella definizione della funzione /* * Draws a circle */ void draw_circle(void) { printf( *** \n ); printf( * *\n ); printf( *** \n ); } 55
Definizione di funzione l intestazione della funzione è simile al prototipo (viene omesso il ; finale) il corpo della funzione contiene le operazioni effettuate dalla funzione l istruzione return è omessa perchè la funzione non ritorna un risultato L istruzione di chiamata a funzione draw_circle(); causa l esecuzione delle 3 printf; il controllo ritorna alla funzione main dopo che il cerchio è stato visualizzato. 56
Definizione di funzione (funzione senza argomenti) sintassi ftype fname(void) { local_declarations executable statements } esempio /* * Displays a block letter H */ void print_h(void) { printf( ** **\n ); printf( ** **\n ); printf( ******\n ); printf( ** **\n ); printf( ** **\n ); } 57
Definizione di funzione (funzione senza argomenti) Viene definita la funzione fname. Nell intestazione della funzione, ftype specifica il tipo del risultato della funzione. Le parentesi graffe racchiudono il corpo della funzione. Gli identificatori dichiarati nelle local declarations sono definiti solo durante l esecuzione della funzione e possono essere usati solo all interno della funzione. Gli executable statements descrivono le operazioni effettuate dalla funzione. 58
il sottoproblema disegna un triangolo è ulteriormente scomposto in due sottoproblemi: disegna linee intersecanti e disegna linea orizzontale. Lo sviluppo top-down viene utilizzato per implementare la funzione che disegna il triangolo: /* * Draws a triangle */ void draw_triangle(void) { draw_intersect(); draw_base(); } 59
/* Draws a stick figure */ #include <stdio.h> /* Function prototypes */ void draw_circle(void); /* Draws a circle */ void draw_intersect(void); /* Draws intersecting lines */ void draw_base(void); /* Draws a base line */ void draw_triangle(void); /* Draws a triangle */ int main(void) { /* Draw a circle. */ draw_circle(); /* Draw a triangle. */ draw_triangle(); 60
/* Draw intersecting lines. */ draw_intersect(); } return (0); /* * Draws a circle */ void draw_circle(void) { printf(" *** \n"); printf(" * * \n"); printf(" *** \n"); } 61
/* * Draws intersecting lines */ void draw_intersect(void) { printf(" / \\ \n"); /* Use 2 \'s to print 1 */ printf(" / \\ \n"); printf("/ \\\n"); } /* * Draws a base line */ void draw_base(void) { } printf("-------\n"); 62
/* * Draws a triangle */ void draw_triangle(void) { draw_intersect(); draw_base(); } 63
Disposizione delle funzioni all interno del programma i prototipi precedono la funzione main (appaiono dopo le direttive #include e #define) le definizioni si trovano dopo la funzione main l ordine relativo delle definizioni di funzioni non influisce sul loro ordine di esecuzione; l ordine di esecuzione è determinato dall ordine in cui vengono effettuate le chiamate Uso dei commenti ogni definizione di funzione è preceduta da un commento che descrive lo scopo della funzione. 64
Ordine di esecuzione delle funzioni e del main i prototipi forniscono al compilatore informazioni sulle funzioni utilizzate ogni chiamata a funzione viene tradotta in un trasferimento del controllo al codice della funzione al termine del corpo di ogni funzione, il compilatore aggiunge un istruzione in linguaggio macchina che trasferisce il controllo all istruzione che segue la chiamata alla funzione 65
Ordine di esecuzione delle funzioni e del main funzione main draw_circle(); draw_triangle(); draw_intersect(); void draw_circle(void) { printf( *** \n ); } printf( * *\n ); printf( *** \n ); ritorna al chiamante 66
Vantaggi derivati dall uso di funzioni astrazione procedurale il main è una sequenza di chiamate a procedura (una per ogni passo principale dell algoritmo); ogni funzione viene implementata separatamente riutilizzo di codice una funzione può essere eseguita più volte all interno di un programma (es. draw_intersect); dopo aver scritto e testato una funzione, posso riciclarla in altri programmi 67
Visualizzare istruzioni per l utente le funzioni senza parametri possono essere usate per separare la visualizzazione di istruzioni per l utente dal corpo del main. Es. programma che calcola area e circonferenza void instruct(void) { printf( Questo programma calcola area\n ); printf( e circonferenza di un cerchio.\n\n ); printf( Per usare il programma, inserire\n ); prinft( il raggio del cerchio dopo il prompt.\n ); } 68
dichiarare prima del main il prototipo della funzione void instruct(void); inserire la chiamata a funzione instruct(); come prima istruzione eseguibile nel corpo del main 69
Funzioni con argomenti di input funzioni void con argomenti di input funzioni con argomenti di input e un singolo risultato funzioni con argomenti multipli corrispondenza tra argomenti attuali e parametri formali area dati della funzione driver per testare funzioni 70
Funzioni con argomenti di input gli argomenti di una funzione sono utilizzati per trasportare informazioni dal chiamante all interno della funzione e viceversa. argomenti di input argomenti usati per passare informazioni dal chiamante alla funzione argomenti di output argomenti usati per ritornare risultati al chiamante 71
Funzioni con argomenti di input L utilizzo degli argomenti rende le funzioni più versatili: una funzione può manipolare dati diversi ad ogni chiamata Es. rim_area = find_area(edge_radius) - find_area(hole_radius); 72
funzioni di tipo void con argomenti di input Es. funzione che stampa un numero reale all interno di una cornice /* * Displays a real number in a box. */ void print_rboxed(double rnum) { printf("***********\n"); printf("* *\n"); printf("* %7.2f *\n", rnum); printf("* *\n"); printf("***********\n"); } 73
print_rboxed(135.68); chiama print_rboxed con rnum = 135.68 void print_rboxed(double rnum) { printf("***********\n"); printf("* *\n"); printf("* %7.2f *\n", rnum); printf("* *\n"); printf("***********\n"); } 74
Effetto della chiamata Quando si effettua la chiamata print_rboxed(135.68) il valore del argomento attuale (135.68) viene passato alla funzione e sostituito al parametro formale (rnum). La funzione print_rboxed visualizza sullo schermo il seguente messaggio: *********** * * * 135.68 * * * *********** 75
Parametri attuali e formali argomento attuale espressione inserita tra le parentesi di una chiamata a funzione parametro formale identificatore che rappresenta il corrispondente argomento attuale nella definizione della funzione 76
Funzioni con argomenti di input e un singolo risultato le funzioni che ritornano un risultato possono essere chiamate all interno di espressioni, come le funzioni di libreria i n p u t.. funzione risultato 77
Esempio: circonferenza del cerchio /* * Computes the circumference of a circle with radius r. * Pre: r is defined and is > 0. * PI is a constant macro representing an * approximation of pi. */ double find_circum(double r) { return (2.0 * PI * r); } 78
Esempio: area del cerchio /* * Computes the area of a circle with radius r. * Pre: r is defined and is > 0. * PI is a constant macro representing an * approximation of pi. * Library math.h is included. */ double find_area(double r) { return (PI * pow(r, 2)); } 79
#define PI 3.14159 radius = 10.0; circum = find_circum(radius); ritorna il risultato 62.8318 double find_circum(double r) { return (2.0 * PI * r); } chiama find_circum con r = 10.0 80
sintassi Definizione di funzione (con argomenti in input e singolo risultato) function interface comment ftype fname (formal parameter declaration list) { local variable declarations executable statements } 81
Definizione di funzione (con argomenti in input e singolo risultato) esempio /* * Finds the cube of its argument. * Pre: n is defined. */ int cube(int n) { return(n * n * n); } 82
Definizione di funzione (con argomenti in input e singolo risultato) L intestazione della funzione specifica il nome della funzione, fname, e il tipo del risultato ritornato dalla funzione, ftype. L intestazione indica inoltre i nomi e i tipi dei parametri formali nella formal parameter declaration list. Note: l intestazione NON termina con il punto e virgola utilizzare void nella formal parameter declaration list per indicare che la funzione non ha argomenti 83
Definizione di funzione (con argomenti in input e singolo risultato) Le parentesi graffe racchiudono il corpo della funzione. Il tipo delle variabili aggiuntive necessarie nella funzione è dichiarato nelle local variable declarations. Gli executable statements specificano le operazioni effettuate sui dati e sulle variabili locali per ottenere il risultato. L esecuzione dell istruzione return ritorna il controllo al chiamante. La funzione ritorna come risultato il valore dell espressione che segue la parola return. 84
Stile: function interface comment Il commento che precede l intestazione della funzione contiene tutte le informazioni necessarie all uso della funzione: descrizione dello scopo della funzione precondizione condizione che viene assunta vera al momento della chiamata postcondizione condizione che sarà vera al termine dell esecuzione della funzione 85
Funzioni con argomenti multipli /* * Multiplies its first argument by the power of * 10 specified by its second argument. * Pre : x and n are defined and * math.h is included. */ double scale(double x, int n) { double scale_factor; /* local variable */ scale_factor = pow(10, n); } return (x * scale_factor); 86
Funzione scale scale(2.5, 2) 2 restituisce il valore 250.0 (che è 2.5 10 ) scale(2.5, -2) -2 restituisce il valore 0.025 (che è 2.5 10 ) La variabile locale scale_factor è definita solo all interno della funzione scale. Come si fa a testare il corretto funzionamento di una funzione? 87
/* * Tests function scale. */ #include <math.h> /* Function prototype */ double scale(double x, int n); int main(void) { double num_1; int num_2; /* Get values for num_1 and num_2 */ printf("enter a real number> "); scanf("%lf", &num_1); printf("enter an integer> "); scanf("%d", &num_2); 88
/* Call scale and display result. */ printf("result of call to function scale is %f\n", scale(num_1, num_2)); } return (0); flusso dell informazione double scale(double x, int n) { double scale_factor; /* local variable - 10 to power n */ scale_factor = pow(10, n); } return (x * scale_factor); 89
Corrispondenza tra argomenti attuali e parametri formali il numero di argomenti attuali usati in una chiamata a funzione deve essere uguale al numero di parametri formali elencati nel prototipo della funzione l ordine degli argomenti determina la corrispondenza tra le due liste. Il primo argomento attuale corrisponde al primo parametro formale; il secondo argomento attuale corrisponde al secondo parametro formale e così via ogni argomento attuale deve essere di un tipo che può essere assegnato al corrispondente parametro formale senza perdita di informazione 90
Area dati della funzione Ogni volta che viene eseguita una chiamata a funzione, viene allocata un area di memoria per memorizzare i dati della funzione: parametri formali variabili locali Quando la funzione termina, l area dati viene persa; viene ricreata (con valori indefiniti) quando la funzione viene chiamata di nuovo. 91
Area dati della funzione scale Area dati del main num_1 2.5 num_2-2 Area dati della funzione scale x 2.5 n -2 scale_factor?? 92
Area dati della funzione scale La variabile locale scale_factor può essere utilizzata solo all interno della funzione scale. Le variabili num_1 e num_2, dichiarate nella funzione main, possono essere utilizzate solo all interno del main. Per renderle utilizzabili a un altra funzione, occorre passarle come parametri. 93
Driver Ogni funzione è un modulo di programma indipendente, quindi può essere testato separatamente dal programma che la usa. Un driver è un piccolo programma scritto per testare una funzione: definisce gli argomenti della funzione chiama la funzione ne visualizza i risultati 94
Prototipo di funzione funzione senza parametri e valore di ritorno void star_line(void); funzione con parametri e valore di ritorno double partition(double x, int n); Chiamata a funzione funzione senza parametri e valore di ritorno star_line(); funzione con parametri e valore di ritorno money = partition(funds, num_kids) + bonus; 95
Definizione di funzione funzione senza parametri e valore di ritorno void star_line(void) { printf( *\n*\n*\n*\n); } funzione con parametri e valore di ritorno /* * Pre: x and n are defined, x >= 0, n > 0 * Post: result is x / n double partition(double x, int n) { return (x / n); } 96