Funzioni. Elementi di informatica IGLP

Documenti analoghi
Esempio di programma che utilizza funzioni

cout << "Inserisci un numero:" << endl; cin >> n; ris = n*2; cout << "Il doppio di " << n << " e " << ris << endl;

Le Funzioni in C. Fondamenti di Informatica Anno Accademico 2010/2011. Corso di Laurea in Ingegneria Civile Politecnico di Bari Sede di Foggia

Fondamenti di programmazione parte 2. Elementi di informatica IGLP

Ambienti di Programmazione per il Software di Base

Procedure e funzioni A. Ferrari

Funzioni. (Passaggio dei parametri per riferimento) Passaggio dei parametri

Parametri by reference. Funzioni. Passaggio dei parametri. Parametri by reference. Soluzione. Problemi

Le funzioni: dichiarazione, definizione e chiamata Il passaggio degli argomenti per valore e riferimento La funzione main() Le regole di visibilità

Funzioni in C. Funzioni. Strategie di programmazione. Funzioni in C. Come riusare il codice? (2/3) Come riusare il codice? (1/3)

Procedura. Procedure e funzioni. Esempio di procedura in C. Procedure in C. Esempio con prototipo. Esecuzione del codice

Strategie di programmazione

METODI in Java. Prof.Angela Bonifati. Metodi e Sottoprogrammi

FUNZIONI. Esempi (pseudo-c): dare un nome a una espressione rendere tale espressione parametrica. float f(){ * sin(0.75); } float f1(int x) {

dare un nome a una istruzione non denota un valore, quindi non c è tipo di ritorno void

Corso sul linguaggio Java

Informatica A (per gestionali) A.A. 2004/2005. Esercizi di programmazione C Funzioni: passaggio di parametri per indirizzo, passaggio di array.

Linguaggio C - sezione dichiarativa: costanti e variabili

Funzioni, Stack e Visibilità delle Variabili in C

Elementi di Informatica

Strutturare il codice: sottoprogrammi

Introduzione al linguaggio C Puntatori

void p(int x) { float y = x * sin(0.75); printf( %f, y); }

Tempo di vita e scope delle variabili

uguale livello gerarchico non vi sono funzioni più importanti di altre main main

C: panoramica. Violetta Lonati

Le classi in java. Un semplice programma java, formato da una sola classe, assume la seguente struttura:

Corso di Informatica A.A

Corso di Informatica Modulo T3 2 Ambiente locale e globale

Introduzione al linguaggio C Puntatori

FUNZIONI. attribuire un nome ad un insieme di istruzioni parametrizzare l esecuzione del codice

Passaggio dei parametri Per valore Il valore viene copiato dall environment esterno all environment della funzione o procedura Cambiamenti dei paramet

FUNZIONI COME COMPONENTI SW FUNZIONI COME COMPONENTI SW FUNZIONI MODELLO CLIENTE/SERVITORE

Il linguaggio C funzioni e puntatori

Informatica (A-K) 12. Linguaggio C -3

FUNZIONI FUNZIONI COME COMPONENTI SW

Passaggio dei parametri

Funzioni, puntatori, strutture. Lab. Calc. AA 2006/07

Fondamenti di Informatica II 3. Funzioni in C++ (parte 1)

Concetto di Funzione e Procedura METODI in Java

Fondamenti di Informatica

Laboratorio di Informatica I

Definizione di classi. Walter Didimo

Nel seguito, istruzione1 e istruzione2 possono essere un blocco di codice { }, cioè più istruzioni

Una procedura permette di#! dare un nome a una istruzione#! rendendola parametrica!! non denota un valore, quindi " non c#è tipo di ritorno!

C++ funzioni Alberto Ferrari. Alberto Ferrari Programmazione di applicazioni SW

Lezione 6: Array e puntatori

Esercitazioni di Fondamenti di Informatica - Lez. 5 30/10/2018

int main(){ int numero; /* numero di cui voglio calcolare il fattoriale */ int fatt; /* memorizzo il fattoriale di numero */ int somma=0;

Il linguaggio C Funzioni e procedure

Linguaggio C: PUNTATORI

L AMBIENTE CODE BLOCKS E L IO

Il linguaggio C. Istruzioni, funzioni, dati strutturati

sqrt #include <iostream> #include <cmath> using namespace std; int main() { int x; cout << Inserire un numero \n ; cin >> x; int main()

Esercizi. La funzione swapint() primo tentativo

Laboratorio di programmazione

Una procedura permette di" void p(int x) { x = x * 2; printf( %d, x); }

nome (lista_parametri) Funzioni funzioni predefinite: sqrt(x) log(x) usare queste funzioni significa: specificare il valore degli argomenti

Le funzioni. Funzioni. Funzioni. Funzioni

Programmazione Procedurale in Linguaggio C++

Matrici. Parte 7. Domenico Daniele Bloisi. Corso di Fondamenti di Informatica Ingegneria delle Comunicazioni BCOR Ingegneria Elettronica BELR

Funzioni. (Passaggio dei parametri per riferimento) Passaggio dei parametri

Variabili e Funzioni. Informatica 1 / 19

Puntatori e array. Violetta Lonati

Gestire le situazioni di errore

ERRATA CORRIGE. void SvuotaBuffer(void); void SvuotaBuffer(void) { if(getchar()!=10) {svuotabuffer();} }

Università degli Studi di Cassino Corso di Fondamenti di Informatica Tipi strutturati: Array. Anno Accademico 2010/2011 Francesco Tortorella

Linguaggio C: le funzioni. Introduzione e sintassi

Programmazione Orientata agli Oggetti in Linguaggio Java

7 - Programmazione procedurale: Dichiarazione e chiamata di metodi ausiliari

Ingegneria Elettronica Ingegneria delle Telecomunicazioni (J-Z) Ing. Antonio Monteleone A.A. 2001/02 3 ciclo

Funzioni. Unità 1. Domenico Daniele Bloisi. Corso di Fondamenti di Informatica Ingegneria delle Comunicazioni BCOR Ingegneria Elettronica BELR

Elementi lessicali. Lezione 4. La parole chiave. Elementi lessicali. Elementi lessicali e espressioni logiche. Linguaggi di Programmazione I

Struttura di un. Struttura dei programmi C

Funzioni e. Alessandra Giordani Mercoledì 16 maggio 2012

Programmazione ad oggetti

Il linguaggio C. Puntatori e dintorni

Linguaggio C: le funzioni. Visibilità variabili e passaggio parametri

Linguaggio C: le funzioni. Introduzione e sintassi

Non ci sono vincoli sul tipo degli elementi di un vettore Possiamo dunque avere anche vettori di

CORSO DI PROGRAMMAZIONE

Lezione 11. Tipo derivato riferimento Passaggio per riferimento Parametri di ingresso e/o uscita

INFORMATICA DI BASE Linguaggio C Prof. Andrea Borghesan

Programmazione Procedurale in Linguaggio C++

L AMBIENTE CODE BLOCKS E L IO

Le strutture /1. struct temp {char titolo[200]; char autore[100]; int pagine; } ; typedef struct temp libro;

L'Allocazione Dinamica della Memoria nel linguaggio C

Dichiarazioni e tipi predefiniti nel linguaggio C

5.4 Istruzione di input L istruzione di input ha la forma:

Elementi di Informatica

Ripasso di programmazione ricorsiva

Lezione 9: Puntatori a funzioni. Tipi enumerativi e orientati ai bit

Transcript:

Funzioni Elementi di informatica IGLP

Questo insieme di trasparenze è stato ideato e realizzato dai ricercatori e professori del Dipartimento di Informatica e Sistemistica dell Università di Napoli. Esse possono essere impiegate liberamente per fini didattici esclusivamente senza fini di lucro, a meno di un esplicito consenso scritto degli Autori. Nell uso dovrà essere esplicitamente riportata la fonte e gli Autori. Gli Autori non sono responsabili per eventuali imprecisioni contenute in tali trasparenze né per eventuali problemi, danni o malfunzionamenti derivanti dal loro uso o applicazione

Outline Le funzioni Il passaggio dei parametri per valore e per riferimento Parametri di ingresso, di uscita e di ingressouscita Il passaggio di parametri const Il passaggio di parametri vettore

Funzioni: cosa sono Le funzioni rappresentano dei contenitori per dei frammenti di codice Esse possono essere invocate ogni qual volta si desideri eseguire uno specifico frammento I frammenti di codice che costituiscono una funzione vengono spesso definiti sotto-programmi (subroutines) Una chiamata a funzione provoca: l esecuzione del codice contenuto nella funzione; una volta che la funzione sia terminata, l esecuzione della istruzione immediatamente successiva alla chiamata.

Esempio di programma che utilizza funzioni

Vantaggi nell uso delle funzioni Con riferimento al programma d esempio notiamo che l uso delle funzioni apporta alcuni vantaggi: maggiore sinteticità una funzione può essere scritta una sola volta ed usata tante volte (p.es. la funzione StampaVettore( )). Inoltre programmi più brevi sono più facilmente manutenibili. maggiore leggibilità da un veloce sguardo del listato appare subito chiaro cosa fa il programma possibilità di scomporre ogni problema in sottoproblemi più semplici si può realizzare il programma in più fasi successive non dovendo preoccuparsi di tutto e subito si può delegare la stesura di parti di programma ad altri individui ciò è diretta conseguenza del maggiore grado di modularità raggiunto. pur sapendo cosa fa una funzione (p.es. OrdinaVettore( )), non è detto che si sappia come lo fa questo permette di concentrarsi più sulla logica del problema che sull implementazione della sua soluzione.

Esempio: la funzione somma

Il prototipo di una funzione Il prototipo di una funzione serve a definire il nome della funzione e il tipo di parametri che tratta, siano essi di ingresso o di uscita <tipo risult.> <NomeFunz.>(<tipo> <nome>, <tipo> <nome>, ); Per esempio: bool DataValida(int giorno, int mese, int anno); bool NumeroPari(int n); float Dividi(float a, float b);

Valori restituiti Dal prototipo di una funzione è possibile dedurre il tipo del valore che assumerà la funzione in seguito alla sua chiamata Il valore assunto dalla funzione può essere utilizzato, per es., all interno di espressioni più complesse: d = Somma(a,b) * Dividi(a,c); // d=(a+b)*a/c L argomento stesso di una funzione potrebbe essere il risultato restituito da un altra funzione_ e = Somma( a, Somma(b, c) ); // e=a+b+c

Procedure Una funzione può anche non restituire alcun valore. In questo caso il suo prototipo sarà del tipo: void Func( ); Le funzioni che non restituiscono alcunché, vengono anche dette procedure, ma in C++ la differenza tra funzioni e procedure resta molto blanda La chiamata ad una procedura è del tipo Func( ); e non ha più senso qualcosa del tipo a = Func( ); Esempi di procedure sono StampaVettore(), e CaricaVettore()

La keyword return Dall interno della funzione, per restituire il giusto valore al chiamante, si usa la keyword return Essa, come effetto collaterale, provoca anche l immediata terminazione della funzione P.es.: //funzione che indica se c è compreso nell intervallo //a..b estremi inclusi (implementazione poco felice) bool Compreso(int a, int b, int c) { if (c < a) return false; if (c > b) return false; return true; } La stessa funzione poteva essere più felicemente realizzata nel modo seguente: bool Compreso(int a, int b, int c) { return ( (c >= a) && (c <= b) ); }

Parametri formali e parametri effettivi Nel prototipo della funzione Compreso( ) bool Compreso(int a, int b, int c) a, b e c sono detti parametri formali. Sono i parametri che la funzione utilizza al suo interno. È come se fosse stata essa stessa ad averli dichiarati. Al momento della definizione della funzione non è necessario conoscere quali saranno i veri parametri su cui essa opererà

Parametri formali e parametri effettivi Nel programma int main() { int x, y, z;... if (Compreso(x, y, z)) cout << z e compreso tra x ed y.\n ; else cout << z non e compreso tra x ed y.\n ; return 0; } all atto della chiamata alla funzione, x, y e z sono detti parametri effettivi, e non sono tenuti ad avere lo stesso nome dei parametri formali

Parametri formali e parametri effettivi All atto della chiamata: il compilatore controlla se il tipo dei parametri attuali corrisponde col tipo dei parametri formali, segnalando eventualmente un errore; sostituisce ciascun parametro formale con il corrispondente parametro attuale; esegue la funzione. La corrispondenza, come anticipato, non avviene per nome, ma per posizione In altre parole al primo parametro formale viene sostituito il primo parametro attuale, al secondo il secondo e così via

La funzione main Anche il main() è una funzione La sua unica caratteristica peculiare è che, per convenzione, è la prima funzione invocata in un programma. È il sistema operativo ad invocare la funzione main() ed a recuperare, al suo termine, il valore restituito attraverso il return Si noti anche che, così come è possibile dichiarare delle variabili locali al main() utili al suo funzionamento, è ugualmente possibile dichiarare delle variabili all interno di tutte le altre funzioni

Esercizi Scrivere il prototipo di una funzione che accetti in ingresso un numero intero e restituisca un valore che indichi se il numero è un numero primo Si implementi poi la funzione Si realizzi infine un programma chiamante che verifichi il corretto comportamento della funzione Per la verifica della proprietà si utilizzi la definizione di numero primo: un numero intero positivo è numero primo se è divisibile solo per 1 e per sé stesso. Utilizzando la funzione per la rivelazione dei numeri primi, si realizzi un programma che, dato un numero intero dall utente, stampi tutti i numeri primi minori o uguali ad esso Scrivere il prototipo di una funzione che accetti in ingresso tre interi e, interpretandoli come giorno, mese ed anno, restituisca un valore che indichi se la data specificata è una data valida. Si implementi poi la funzione. Si realizzi infine un programma chiamante (main) che verifichi il corretto comportamento della funzione Realizzare, attraverso l uso di un apposita funzione, un programma che calcoli la distanza tra due punti di cui l utente inserisce le coordinate in un sistema di riferimento cartesiano bidimensionale

Il passaggio dei parametri per valore Si consideri il seguente programma con il relativo output: Questo comportamento apparentemente strano si spiega attraverso la modalità di passaggio dei parametri impiegata in questo caso particolare

Il passaggio dei parametri per valore Il passaggio dei parametri in C++, in assenza di esplicite direttive, avviene secondo la modalità detta per valore Questo significa che, all atto della chiamata di una funzione, il compilatore realizza una copia dei parametri attuali e la associa ai parametri formali la funzione lavora dunque su delle copie dei parametri attuali localizzate in aree di memoria completamente diverse, e non sui parametri attuali veri e propri Le copie vengono distrutte al termine della funzione: del loro valore, eventualmente alterato all interno della funzione, non resta traccia

Il passaggio dei parametri per valore Vantaggi: dal punto di vista del chiamante: il chiamante di una funzione può essere certo che i parametri ad essa passati non potranno essere restituiti alterati in seguito alla chiamata dal punto di vista della funzione: la funzione, se lo crede opportuno, può modificare i parametri a suo piacimento con la certezza che le modifiche non saranno visibili all esterno di essa Svantaggi: l occupazione di memoria risulta doppia rispetto al necessario il tempo per effettuare la copia dei parametri, specialmente nel caso in cui questi siano appartenenti a tipi strutturati di grosse dimensioni, può degradare le prestazioni di un programma

Il passaggio dei parametri per valore Al di là dei vantaggi e svantaggi elencati, ci sono dei casi in cui il comportamento descritto è del tutto indesiderato Per es., riprendiamo il caso della funzione Azzera: void Azzera(int numero) { numero = 0; } In questo caso si desidera che il parametro attuale venga modificato in seguito alla chiamata alla funzione, ma il meccanismo di protezione dovuto al passaggio dei parametri per valore impedisce che questo possa avvenire

Il passaggio dei parametri per riferimento Per risolvere il problema è necessario esplicitamente richiedere al compilatore che all interno della funzione si possa lavorare non su delle copie, ma sui parametri veri e propri Questo è possibile attraverso il passaggio dei parametri per riferimento In questo caso alla funzione viene passata non una copia del parametro attuale, ma il riferimento ad esso, cioè l indirizzo di memoria Per richiedere questo tipo di passaggio bisogna aggiungere il carattere & tra il tipo ed il nome del parametro in questione

Il passaggio dei parametri per riferimento La versione corretta della funzione Azzera risulta dunque: void Azzera(int& numero) { numero = 0; } In questo caso il compilatore permette alla funzione di lavorare direttamente sull area di memoria in cui è contenuto il parametro attuale che corrisponderà al parametro formale numero, senza quindi che di esso ne venga fatta una copia

Vantaggi: Il passaggio dei parametri per riferimento il passaggio è più efficiente dal momento che, a prescindere dalle dimensioni del dato, quello che deve essere passato è sempre e solo un indirizzo di memoria Svantaggi: si perde il meccanismo di protezione garantito dal passaggio dei parametri per valore

Valore o riferimento? Abbiamo visto che entrambi i tipi di passaggi sono indispensabili per un corretto comportamento delle funzioni in tutti i casi che si possono verificare I parametri di una funzione convogliano informazioni tra il chiamante e la funzione chiamata, in entrambe le direzioni È possibile individuare il tipo di passaggio che deve essere di volta in volta utilizzato attraverso l analisi della direzione che le informazioni hanno rispetto alla funzione chiamata In altre parole bisogna capire se le informazioni trasportate dalle variabili di passaggio sono di ingresso alle funzioni chiamate, di ingresso-uscita o di uscita

Parametri di ingresso, di uscita e di ingresso-uscita

Parametri di ingresso, di uscita e di ingresso-uscita Definiamo i parametri di una funzione: parametri di ingresso, se ai fini della corretta esecuzione della funzione è sufficiente, per la funzione stessa, esclusivamente leggere il loro valore; p.es.: NumeroPari(n); parametri di uscita, se essi rappresentano esclusivamente un supporto per convogliare informazioni verso l esterno della funzione; p.es.: CheOreSono(t); parametri di ingresso-uscita, se il loro valore all ingresso della funzione è significativo ai fini della elaborazione che essa realizza ma vengono anche alterati per convogliare informazioni verso il chiamante; p.es.: Raddoppia(n).

Parametri di ingresso, di uscita e di ingresso-uscita Le precedenti osservazioni ci indicano dunque che: i parametri di ingresso sono preferibilmente scambiati per valore. i parametri di uscita non possono essere scambiati per valore, altrimenti le modifiche apportate ad essi non sarebbero visibili all esterno della funzione. Devono dunque essere scambiati per riferimento. i parametri di ingresso-uscita, analogamente a quelli di uscita, non possono essere scambiati per valore, ma devono essere scambiati per riferimento. Il C++, pertanto, nell ottica della modalità di passaggio dei parametri, non fa grande differenza tra parametri di uscita e di ingresso-uscita. Si tenga presente che una generica funzione può avere più parametri di ingresso, uscita e ingresso-uscita contemporaneamente. P. es.: void ModuloFase(float PReale, float PImmag, float& Modulo, float& Fase);

Il passaggio di parametri const E se è necessario passare un dato di grosse dimensioni conservando l efficienza e proteggendolo comunque da modifiche indesiderate? Una soluzione è rappresentata dalla clausola const

Il passaggio di parametri const Durante lo scambio dei parametri, se si fa anticipare al tipo del parametro la keyword const, si impedisce del tutto alla funzione di modificare il parametro all interno di essa. P.es.: int NumeroPari(const int& n); int QuantiHanniHa(const TPersona& p); Nel caso di passaggio per riferimento, la clausola const risolve il problema di modifiche indesiderate ai parametri,consentendo contemporaneamente di sfruttare l efficienza intrinseca di questa modalità

Il passaggio di parametri const Il prototipo di una funzione che calcola la radice quadrata di un numero potrebbe essere: long double sqrt(long double x); All interno della funzione, se il parametro x viene alterato, le sue modifiche non saranno propagate verso l esterno Un prototipo alternativo potrebbe essere: long double sqrt(const long double& x); In questo caso l efficienza aumenta senza compromettere il meccanismo di protezione

Il passaggio dei vettori Si consideri il seguente programma con il relativo output: I vettori, passati come parametri alle funzioni, assumono un comportamento apparentemente strano Stando al passaggio dei parametri per valore, l output riportato di fianco sembra inspiegabile

Il passaggio dei vettori Questo strano comportamento discende dalla particolare proprietà dei vettori secondo la quale il nome di un vettore rappresenta un puntatore alla locazione in cui si trova il primo elemento dell array Il parametro che quindi viene scambiato per valore, e pertanto viene copiato all atto del passaggio, non è il vettore ma il suo puntatore Ecco perché le modifiche interne alla funzione si propagano anche all esterno: in entrambi i casi si lavora sempre sulla stessa area di memoria. Ancora una volta, volendo evitare questo inconveniente è possibile passare il vettore con la clausola const Ciò avviene tipicamente nel caso di funzioni che accettino vettori di ingresso. P.es.: void StampaVettore(const TVettore v, int nelem); La funzione StampaVettore in questo modo non può, neanche se volesse, alterare il vettore v Qualsiasi tentativo di farlo produrrebbe un errore di compilazione Si noti che l unico modo per conoscere all interno di una funzione il numero di elementi significativi di un vettore passato è quello di indicarlo esplicitamente come parametro di passaggio aggiuntivo

Riepilogo

Esercizi Scrivere il prototipo di una funzione che calcoli il minimo di un vettore Scrivere il prototipo di una funzione che realizzi il concatenamento di due vettori Scrivere il prototipo di una funzione che realizzi il prodotto scalare di due vettori