SlideShare a Scribd company logo
Funzioni
          Parte I
       Definizione,
Dichiarazione o Prototipo,
        Chiamata
Blocco
• Sequenza di definizioni e istruzioni racchiuse tra parentesi
  graffe
     {
            <dichiarazione1 o istruzione1>
            <dichiarazione2 o istruzione2>
            ...
     }
• In C, parte dichiarativa ed esecutiva devono essere
  separate:
     {
            <dichiarazioni>
            <istruzioni>
            ...
     }


Programmazione - Paolo Valente, 2008/2009
Blocco ed istruzione composta
• Per semplicità in precedenza abbiamo definito
  l'istruzione composta come un caso particolare di
  blocco in cui c'erano solo istruzioni
   – In verità un'istruzione composta si esprime
     esattamente mediante un blocco
   – Quindi si possono inserire dichiarazioni anche in
     un'istruzione composta
• Inoltre con i blocchi non si esprimono solo le istruzioni
  composte, ma anche ad esempio i corpi delle
  funzioni, come vedremo a breve ...




Programmazione - Paolo Valente, 2008/2009
Utilità delle funzioni
• Per evidenziare l'utilità delle funzioni, scriviamo

      1) un programma che legga in ingresso un numero
        intero non negativo e dica all'utente se il numero è
        primo (o altrimenti non stampi nulla)
      2) un programma che legga in ingresso due numeri
        interi non negativi e, se e solo se sono entrambi
        primi, dica all'utente se si tratta di due numeri primi
        gemelli (ossia che differiscono esattamente di due
        unità l'uno dall'altro)
        Es.: 5 e 7 sono primi gemelli
     Cominciamo dal primo programma
•




Programmazione - Paolo Valente, 2008/2009
Programma 1 (prime idee)
• Un numero è primo se è divisibile solo per 1 e per se stesso.
  Quindi, occorre provare a dividere N per tutti i numeri 2≤ i ≤ N-1.
  Se nessun numero i risulta essere un divisore di N, allora N è
  primo. Funziona? Sì, ma si può fare meglio
• IDEA 1: Poiché i numeri pari non sono primi, eliminiamo subito la
  possibilità che N sia pari
• IDEA 2: Non c’è bisogno di provare tutti i numeri fino a N-1, ma è
  sufficiente provare a dividere N per tutti i numeri dispari 3≤ i ≤
  (N/2): se nessun numero i risulta essere un divisore di N, allora N
  è primo
• IDEA 3: Non c’è bisogno di provare tutti i numeri fino a N/2, ma è
  sufficiente provare a dividere N per tutti i numeri dispari
  3≤ i ≤ √N: se nessun numero i risulta essere un divisore di N,
  allora N è primo
Programmazione - Paolo Valente, 2008/2009
Programma 1 (Algoritmo)
• Se N è 1, 2 o 3, allora senz’altro N è un numero primo


• Altrimenti, se è un numero pari, certamente N non è primo


• Se così non è (quindi se N è dispari e >3), occorre tentare
  tutti i possibili divisori dispari da 3 in avanti, fino a
  static_cast<int>(sqrt(N))
   – Ove sqrt(N) è una funzione che ritorna √N, mentre
      l'espressione static_cast<int>(sqrt(N)) è uguale al più
      grande numero intero non maggiore di √N
    – Nota: ci sta bene utilizzare la parte intera di sqrt(N) perché il
      potenziale divisore sarà senz'altro un numero intero
Programmazione - Paolo Valente, 2008/2009
Programma 1 (Rappresentazione
                 informazioni)
• Variabile per contenere il numero: int n
•   Può tornare poi utile una variabile int max_div che contenga la parte
    intera della radice quadrata del numero
     – Serve poi una variabile ausiliaria (int i) come indice per andare da 3
        a max_div


• Per utilizzare la funzione sqrt() occorre:
   – includere anche <cmath> (<math.h> in C)
     Es.:     #include <iostream>
              #include <cmath>
   – aggiungere l'opzione -lm nell'invocazione del g++

        Es.: g++ -lm nomefile.cc
Programmazione - Paolo Valente, 2008/2009
Programma 1
  main()
  {
    int max_div, n ; cin>>n ;
       if (n>=1 && n<=3) { cout<<”primo”<<endl ; return ; }
       if (n%2==0) return;                  /* no perché numeri pari */
       max_div = static_cast<int>(sqrt(n));
       for(int i=3; i<=max_div; i=i+2)
          if (n%i==0) return ;    /* no, perché è stato trovato
                                    un divisore */
       cout<<”primo”<<endl ;
   }



Programmazione - Paolo Valente, 2008/2009
Secondo programma
• Veniamo ora al secondo programma, che ricordiamo
  era:
     Un programma che legge in ingresso due numeri
•

     interi non negativi e, se e solo se sono entrambi primi,
     comunica all'utente se si tratta di due numeri primi
     gemelli (ossia che differiscono esattamente di due
     unità l'uno dall'altro)
     Riutilizzando le righe di codice già scritte, potremmo
•

     scrivere ad esempio:




Programmazione - Paolo Valente, 2008/2009
Programma 2 1/2
  main()
  {
    int n1, n2 ; cin>>n1>>n2 ;
    int max_div; bool n1_is_prime = false,
      n2_is_prime = false ;
      if (n1>=1 && n1<=3) n1_is_prime = true ;
      else if (n1%2 != 0) {
         int i; max_div = static_cast<int>(sqrt(n1));
         for(i=3; i<=max_div; i=i+2)
              if (n1%i==0) break ;
         if (i > max_div)
             n1_is_prime=true ;
       }
Programmazione - Paolo Valente, 2008/2009
Programma 2 2/2
      if (n2>=1 && n2<=3) n2_is_prime = true ;
      else if (n2%2 != 0) {
             int i ; max_div = static_cast<int>(sqrt(n2));
             for(i=3; i<=max_div; i=i+2)
                 if (n2%i==0) break ;
             if (i > max_div)
                n2_is_prime=true ;
         }
      if (n1_is_prime && n2_is_prime)
          if (n1 == n2 – 2 || n2 == n1 – 2)
               cout<<”n1 ed n2 sono due primi gemelli”<<endl ;
  }

Programmazione - Paolo Valente, 2008/2009
Considerazioni
• Quanto è leggibile il programma?

      – Non molto

• Come mai?

• Fondamentalmente perché c'è codice abbastanza
  lungo ripetuto due volte

• Quale sarebbe stato il livello di leggibilità se avessimo
  avuto a disposizione una funzione is_prime() a cui
  passavamo come argomento un numero e ci diceva
  se era primo?
Programmazione - Paolo Valente, 2008/2009
Programma 2 Altra versione
  main()
   {
     int n1, n2 ; cin>>n1>>n2 ;
     if (is_prime(n1) && is_prime(n2))
        if (n1 == n2 – 2 || n2 == n1 – 2)
            cout<<”n1 ed n2 sono due primi gemelli”<<endl ;
  }

  • Molto più breve, leggibile e facile da capire
  • Non contiene codice duplicato
  • Per arrivare a questo risultato dobbiamo imparare a
    definire ed utilizzare le funzioni ...


Programmazione - Paolo Valente, 2008/2009
Indice Lezioni Linguaggio C/C++

√ Tipi di dato primitivi (focus su int)

√ Dichiarazioni e Definizioni

√ Espressioni

√ Istruzioni

• Funzioni




Programmazione - Paolo Valente, 2008/2009
Concetto di funzione
• L’astrazione di funzione è presente in tutti i linguaggi di
  programmazione di alto livello

• Una funzione è un componente software che rispecchia
  l'astrazione matematica di funzione:
                               f : A × B × ... × Q → S
      – molti ingressi possibili (corrispondenti ai valori su cui operare)
      – una sola uscita (corrispondente al risultato o valore di ritorno)

• Per calcolare il valore di ritorno della funzione dovranno
  essere eseguite una serie di istruzioni
   – In C/C++ tali istruzioni sono specificate mediante un
     blocco, a cui ci si riferisce tipicamente come il corpo
     della funzione
Programmazione - Paolo Valente, 2008/2009
Procedura
• Altri linguaggi (ma non il C/C++!) introducono anche
  l’astrazione di procedura, che cattura la sola astrazione
  dell'esecuzione di un insieme di azioni, senza ritornare
  risultati
• Comunque, come vedremo è IMMEDIATO DA EMULARE
  IN C/C++ mediante funzioni dal valore di ritorno vuoto




Programmazione - Paolo Valente, 2008/2009
I tre elementi fondamentali per
               comprendere le funzioni

• Definizione e dichiarazione della funzione

• Uso della funzione (chiamata)

• Esecuzione della funzione
  (record di attivazione)
      – Si vedrà in seguito




Programmazione - Paolo Valente, 2008/2009
Definizione di funzione
• Una definizione di funzione è costituita da
  una intestazione e da un corpo, definito
  mediante un blocco




Programmazione - Paolo Valente, 2008/2009
Esempi di intestazioni
 int           fattoriale (int n)
                  Nome della
  Tipo                                       Lista dei parametri
                  funzione
risultato                                    formali

 int               somma3 (int x, int y, int z)
  Tipo                Nome della                       Lista dei parametri
risultato             funzione                               formali

 void              stampa_n_volte (int n)
  Tipo                Nome della funzione                 Lista dei parametri
risultato                                                       formali

 void              stampa_2_volte (void)
                                                     Lista dei parametri formali vuota
                      Nome della
  Tipo
                                                     (void può essere omesso).
                      funzione
risultato
                                                     LE PARENTESI SERVONO SEMPRE
 Programmazione - Paolo Valente, 2008/2009
Sintassi definizione di funzione
• Come già detto, una definizione di funzione è
  costituita da una intestazione e da un corpo, definito
  mediante un blocco
  <def-funzione> ::= <intestazione-funzione> <blocco>

        <intestazione-funzione> ::=
          <nomeTipo> <nomeFunzione> ( <lista-parametri> )

        <lista-parametri> ::=
           void | <def-parametro> { , <def-parametro> }

        <def-parametro> ::= <nomeTipo> <identificatore>

Programmazione - Paolo Valente, 2008/2009
Definizione di funzione (cont.)
L’intestazione specifica nell’ordine:
• Tipo del risultato (void se non c’è risultato);
  corrisponde alla procedura di altri linguaggi
• Nome della funzione
• Lista dei parametri formali (in ingresso)
      – void se la lista è vuota (non ci sono parametri)
            o in questo caso può anche essere omessa la lista stessa
      – una sequenza di definizioni di parametri, se la lista non
        è vuota


Programmazione - Paolo Valente, 2008/2009
Definizione di funzione (cont.)
Il corpo della funzione è costituito da un blocco:
• Delimitato da parentesi graffe { }
• Dichiarazione/definizione di variabili locali al
   blocco di funzione
• Lista di istruzioni




Programmazione - Paolo Valente, 2008/2009
I tre elementi fondamentali per
               comprendere le funzioni

• Definizione e dichiarazione della funzione

• Uso della funzione (chiamata)

• Esecuzione della funzione
  (record di attivazione)




Programmazione - Paolo Valente, 2008/2009
Chiamata di funzione
• Una chiamata di funzione è costituita dal nome della
  funzione e dalla lista dei parametri attuali tra
  parentesi tonde:
   <chiam-funzione> ::=
          <nomeFunzione> ( <lista-parametri-attuali> )
• La chiamata di una funzione è una espressione
• Un parametro attuale è una espressione il cui
  risultato è il valore da assegnare al parametro
  formale che si trova in quella posizione
    – Ci torneremo sopra a breve
Programmazione - Paolo Valente, 2008/2009
Esempio
  void fun(int a)
  {
                                                           Definizione
    cout<<a<<endl ;
  }

  int main()
                                             Invocazione
  {
     fun(3) ;
  }

Programmazione - Paolo Valente, 2008/2009
Proviamo ...
• ... a scrivere, compilare ed eseguire un
  programma in cui
      – Si definisce una funzione di nome fun, che
        ● non prende alcun parametro in ingresso

        ● non ritorna alcun valore

        ● Stampa sullo schermo un messaggio

      ● Si invoca tale funzione all'interno della funzione

        main e si esce




Programmazione - Paolo Valente, 2008/2009
Soluzione
void fun()
{
  cout<<quot;Saluti dalla funzione funquot;<<endl ;
}

main()
{
  fun() ;
}

Programmazione - Paolo Valente, 2008/2009
Lista dei parametri formali e attuali
• Lista parametri formali: argomenti dichiarati
  nella definizione di funzione
  Devono essere variabili o costanti con nome

• Lista parametri attuali: argomenti inseriti al
  momento della chiamata di funzione
   Espressioni separate da virgole, ove ciascuna
   espressione puà essere una:
    –   costante
    –   variabile
    –   espressione aritmetica o logica
    –   …

Programmazione - Paolo Valente, 2008/2009
Dinamica parametri formali e attuali
• La corrispondenza tra parametri formali e attuali è
  posizionale, con in più il controllo di tipo. Si presume
  che la lista dei parametri formali e la lista dei parametri
  attuali abbiano lo stesso numero e tipo di elementi (l'uso
  della conversione di tipo si vedrà in seguito)

• La corrispondenza tra i nomi dei parametri attuali e
  formali non ha nessuna importanza. Gli eventuali nomi di
  variabili passate come parametri attuali possono essere gli
  stessi o diversi. Conta solo la posizione all'interno della
  chiamata

• Non appena parte l'esecuzione di una funzione, ciascuno
  dei parametri formali viene definito (come variabile locale
  alla funzione) ed inizializzato al valore del corrispondente
  parametro attuale

Programmazione - Paolo Valente, 2008/2009
Collocazione definizioni di funzione
 Una funzione non può essere definita all'interno
 di un'altra funzione
int main()
{
    void fun()
    {
        cout<<quot;Saluti dalla funzione funquot;<<endl ;
    }

      fun() ;
      return 0 ;
}
Programmazione - Paolo Valente, 2008/2009
Ancora sui parametri formali 1/2
 Un parametro formale non è altro che una
 variabile locale alla funzione
        Definizioni (quasi) equivalenti di
        una variabile locale i
void fun(int i)                                 void fun()
{                                               {
                            Istruzione legale
            i++ ;                                      int i ;
            cout<<i ;                                  i++ ;
}                                                      cout<<i ;
                                                }
Programmazione - Paolo Valente, 2008/2009
Ancora sui parametri formali 2/2
 Unica differenza (ma molto importante)
 i è inizializzata col valore del
 parametro attuale                                   void fun()
                                                     {
void fun(int i)
                                                            int i ;
{
                                                            i++ ;
            i++ ;
                                                            cout<<i ;
            cout<<i ;
                                                     }
}
                                   i ha un valore iniziale casuale

Programmazione - Paolo Valente, 2008/2009
Istruzione return 1/2
• Viene usata per far terminare l'esecuzione della funzione e
  far proseguire il programma dall'istruzione successiva a
  quella con cui la funzione è stata invocata, ossia per
  restituire il controllo alla funzione chiamante, e, se la
  funzione ha tipo di ritorno diverso da void, restituire il valore
  calcolato dalla funzione, ossia il risultato della funzione
• Sintassi nel caso di funzioni con tipo di ritorno diverso da
  void:
  return (<espressione>) ;
  oppure semplicemente
  return <espressione> ;
    <espressione> deve essere del tipo di ritorno specificato
      nell’intestazione della funzione
• Sintassi nel caso di funzioni con tipo di ritorno void:
  return ;
Programmazione - Paolo Valente, 2008/2009
Istruzione return 2/2
• Eventuali istruzioni della funzione successive
  all’esecuzione del return non saranno eseguite!
• Nel caso della funzione main l’esecuzione dell'istruzione
  return fa uscire dall'intero programma
• Una funzione con tipo di ritorno void può terminare o
  quando viene eseguita l'istruzione return o quando
  l'esecuzione giunge in fondo alla funzione
• Al contrario, una funzione con tipo di ritorno diverso da
  void deve sempre terminare con una istruzione return,
  perché bisogna specificare il valore di ritorno




Programmazione - Paolo Valente, 2008/2009
I tre elementi fondamentali per
               comprendere le funzioni

• Definizione e dichiarazione della funzione

• Uso della funzione (chiamata)

• Esecuzione della funzione
  (record di attivazione)




Programmazione - Paolo Valente, 2008/2009
Esecuzione di istruzioni e valore di
                  ritorno
• La chiamata di una funzione è una espressione
• Due casi:
    – Funzioni void: la chiamata di funzione va considerata
      solamente come l'invocazione di un insieme di istruzioni
      (procedura)
    – Funzioni che ritornano un valore: la chiamata di funzio-
      ne va considerata come un'espressione il cui valore di
      ritorno (calcolato eseguendo le istruzioni della funzione) è
      di tipo uguale al tipo di ritorno della funzione, e può essere
      utilizzato come fattore all'interno di espressioni composte

        Esempio:
        Supponendo che fun() ritorni un valore di tipo int:
         int b = fun(a) + 1 ;
Programmazione - Paolo Valente, 2008/2009
Esercizi
• funz_max.cc
• funz_fattoriale.cc




Programmazione - Paolo Valente, 2008/2009
Anatomia funzione fattoriale
 int           fattoriale (int n)
                                                               INTESTAZIONE
                Nome della Lista dei parametri
Tipo
                funzione
ritorno                    formali
   {
           int fatt;                    Definizioni locali
                                        alla funzione

                                            Restituzione del
           if (n==0) return 1;                                 CORPO
                                            valore
           for (int i=1; i<=n; i++)
               fatt = fatt*i;
                                      Restituzione del
           return fatt;
                                      valore
       }

Programmazione - Paolo Valente, 2008/2009
Progetto di una funzione
•        Scegliere un nome significativo per la funzione

•        La funzione deve ricevere qualche dato dalla funzione
         chiamante?
            Se sì, elencare ed identificare tutti i tipi di dato da passare alla
         funzione (questa è chiamata la lista dei parametri o la lista degli
         argomenti).
            Se no, la lista dei parametri è void

         La funzione deve restituire un dato dalla funzione
•

         chiamante?
             Se sì, identificare il tipo di dato  corrisponderà al tipo di ritorno
         della funzione
             Se no, il tipo della funzione è void


    Programmazione - Paolo Valente, 2008/2009
Dichiarazione della funzione
• Nel linguaggio C/C++ si possono utilizzare solo oggetti
  precedentemente dichiarati
• Questo vale anche per le funzioni, che quindi possono
  essere invocate solo dopo essere state precedentemente
  dichiarate
   – Finora abbiamo visto solo definizioni di funzione
   – Sono in effetti un caso di dichiarazione: quello in cui si
      definisce anche il corpo della funzione stessa
        o Comportano l'allocazione di spazio in memoria per le
          variabili e le istruzioni
• Ci sono diverse situazioni in cui è utile o necessario
  utilizzare una funzione definita altrove o successivamente
• Ad esempio, nel caso di ...
Programmazione - Paolo Valente, 2008/2009
Chiamate incrociate
void fun1()
{
   cout<<”fun1”<<endl ;
   fun2();
                       • Ancora non è stata dichiarata!
}
                       • Invertire l'ordine di definizione
                         delle funzioni non risolverebbe
void fun2()
                         il problema ...
{
   cout<<”fun2”<<endl ;
   fun1();
}

Programmazione - Paolo Valente, 2008/2009
Dichiarazione della funzione
• Una dichiarazione (senza definizione) o prototipo è
  costituita dalla sola intestazione di una funzione seguita da ;
<dich-funzione> ::= <intestazione-funzione> ;

  <intestazione-funzione> ::=
       <nomeTipo> <nomeFunzione> ( <lista-parametri> )

  <lista-parametri> ::=
       void | <dich-parametro> { , <dich-parametro> }

  <dich-parametro> ::= <nomeTipo> [<identificatore>]

                                            Opzionale !
Programmazione - Paolo Valente, 2008/2009
Soluzione chiamate incrociate ...
void fun2() ;

void fun1()
{
    cout<<”fun1”<<endl ;
    fun2();
}

void fun2()
{
    cout<<”fun2”<<endl ;
    fun1();
}
Programmazione - Paolo Valente, 2008/2009
Altri esempi di prototipi
 int fattoriale (int); /* della funzione precedente */
 …
 int fattoriale (int n)
  {
    int i, fatt=1;
    for (i=1; i<=n; i++)
          fatt = fatt*i;
      return(fatt);
  }
 ___________________________________
 int max (int, int, int) ; /* calcola il max di 3 int */


Programmazione - Paolo Valente, 2008/2009
Prototipi e definizioni
• Il prototipo:
     – è un puro “avviso ai naviganti”
     – non produce alcun byte di codice
     – quindi, se lo si ripete non succede niente di male
       (basta che non ci siano due dichiarazioni in contraddizione)
     – può comparire anche dentro un'altra funzione

• La definizione, invece:
     – contiene il vero codice della funzione
     – non può essere duplicata!!
       (altrimenti ci sarebbero due codici per la stessa funzione)
     – il nome dei parametri formali, non necessario in un prototipo, è più
       importante in una definizione

    QUINDI: il prototipo di una funzione può comparire più
    volte, ma la funzione deve essere definita una sola volta.
Programmazione - Paolo Valente, 2008/2009
I tre elementi fondamentali per
               comprendere le funzioni

• Definizione e dichiarazione della funzione

• Uso della funzione (chiamata)

• Esecuzione della funzione
  (record di attivazione)




Programmazione - Paolo Valente, 2008/2009
Esempio: programma (errato)
    #include <iostream>

    using namespace std ;

    int main()
    {
         int a, b;
         cin>>a>>b ;
         cout<<quot;Il massimo tra quot;<<a<<quot; e quot;<<b<<quot; e' quot;<<max(a,b)<<endl ;
         return 0 ;
    }

    int max(int a, int b)
    {
         if (a > b)
              return a ;
         return b ;
    }

Programmazione - Paolo Valente, 2008/2009
Esempio: programma (corretto) 1/2
    #include <iostream>

    using namespace std ;

    int max(int a, int b)
    {
         if (a > b)
              return a ;
         return b ;
    }

    int main()
    {
         int a, b;
         cin>>a>>b ;
         cout<<quot;Il massimo tra quot;<<a<<quot; e quot;<<b<<quot; e' quot;<<max(a,b)<<endl
           ;
         return 0 ;
    }
Programmazione - Paolo Valente, 2008/2009
Esempio: programma (corretto) 2/2
    #include <iostream>
    using namespace std ;
                                            Tipo dei parametri
    int max(int, int) ;
                                            Ad esempio, scrivere
    int main()                              int max(int a, int c) ;
    {
                                            sarebbe stato equivalente
         int a, b;
         cin>>a>>b ;
         cout<<quot;Il massimo tra quot;<<a<<quot; e quot;<<b<<quot; e' quot;<<max(a,b)<<endl ;
         return 0 ;
                                                    Parametri attuali
    }
                                                         (espressioni)
    int max(int a, int b)
    {
         if (a > b)
                                                   Parametri formali
              return a ;
                                                      (variabili)
         return b ;
    }

Programmazione - Paolo Valente, 2008/2009
Esercizio 1 (Specifica)
• Scrivere una funzione che verifichi se un
  numero naturale fornito dal main() è primo
• La funzione deve restituire false se il numero
  non è primo, true se il numero è primo
• E' proprio la funzione che ci serve per
  completare il programma che abbiamo usato
  per introdurre l'utilità delle funzioni all'inizio di
  questa presentazione



Programmazione - Paolo Valente, 2008/2009
Esercizio 1 (Programma)
  bool isPrime(int n)
   {
     int max_div ;
                                              /* 1,2,3 → sì */
      if (n>=1 && n<=3) return true;
      if (n%2==0) return false;             /* no perché numeri pari */
     max_div = static_cast<int>(sqrt(n)) ;
     for(int i=3; i<=max_div; i=i+2)
        if (n%i==0) return false;    /* no perché è stato trovato
                                        un divisore */
    return true;
   }



Programmazione - Paolo Valente, 2008/2009
Istruzione vuota
                                 ;
• E' un semplice
• Non fa nulla
• Sintatticamente è trattata come una qualsiasi altra
  istruzione
• Esempio:
  // ciclo che si ferma quando num è primo
  for(int num = 10001 ; ! isPrime(num) ; num += 2)
       ; // non fa nulla




Programmazione - Paolo Valente, 2008/2009
Esercizio 2 (Specifica)


• Scrivere una funzione radice che calcoli la
  radice quadrata (intera) di un valore naturale
  N.




Programmazione - Paolo Valente, 2008/2009
Esercizio 2 (Idea e Algoritmo)
int radice(int n);
 < restituisce il massimo intero x tale che x*x ≤ n >


• Considera un naturale dopo l’altro a partire da 1 e
  calcolane il quadrato
• Fermati appena tale quadrato supera n
• Il risultato corrisponde al valore dell’ultimo numero tale per
  cui vale la relazione: x*x ≤ n




Programmazione - Paolo Valente, 2008/2009
Esercizio 2 (Programma)

  int radice_intera(int n)
   {
     int radice;
     for (int i=1; i <= n; i++)
          if (i*i>n) radice=i-1;
     return radice;
   }

                                            Funziona?

Programmazione - Paolo Valente, 2008/2009
Esercizio 2 (Programma –versione OK)

  int radice_intera(int n)
   {
     int i, radice=1;
     for (i=1; i*i <= n; i++)
              ;           // istruzione vuota
       radice=i-1;
      return radice;
     }



Programmazione - Paolo Valente, 2008/2009
Nota sul passaggio dei
            parametri in C/C++



Programmazione - Paolo Valente, 2008/2009
Passaggio dei parametri
• Per “passaggio dei parametri” si intende
  l’associazione fra parametri attuali e parametri
  formali che avviene al momento della chiamata di
  una funzione

• L'unico meccanismo adottato in C, è il
  PASSAGGIO PER VALORE

• Come vedremo, in C++ disponiamo anche del
  passaggio per riferimento

Programmazione - Paolo Valente, 2008/2009
Passaggio dei parametri per
                    valore
Le locazioni di memoria corrispondenti ai parametri formali:
• Sono allocate al momento della chiamata della funzione
• Sono inizializzate con i valori dei corrispondenti parametri attuali
   trasmessi dalla funzione chiamante
• Vivono per tutto il tempo in cui la funzione è in esecuzione
• Sono deallocate quando la funzione termina

QUINDI
• La funzione chiamata riceve copia dei valori dei parametri attuali
  passati dalla funzione chiamante
• Tali copie sono sue copie private che servono solo per inizializzare i
  parametri formali
• Ogni modifica ai parametri formali è strettamente locale alla funzione
• I parametri attuali della funzione chiamante non saranno mai
  modificati!

Programmazione - Paolo Valente, 2008/2009
Esempio
• Prototipo di funzione
    double CalcDistance (int, int, int, int);

• Definizione di funzione
   double CalcDistance (int px1, int py1, int px2, int py2)
   {
      px1 = pow (px1 - px2, 2);
      py2 = pow (py1 - py2, 2);
                                           Il collegamento tra parametri
      return sqrt(px1 + py2) ;
                                           formali e parametri attuali si ha
   }
                                           solo al momento della chiamata.
                                           Sebbene px1 e py2 vengano
• Chiamata di funzione                     modificati all’interno della
   int a= 9, b= 5, c=4, d=12; double dist; funzione, i valori dei
   cout<<a<<b<<c<<d<<endl;                 corrispondenti parametri attuali
   dist = CalcDistance (a, b, c, d);       (a, d) rimangono inalterati.
                                           Quindi gli stessi valori di a e d
   cout<<a<<b<<c<<d<<dist<<endl;
                                           sono stampati prima e dopo
 Programmazione - Paolo Valente, 2008/2009
Esempio 2
  int fattoriale (int n)
     {
         int fatt=1;          // con variabile ausiliaria i
         for (int i=1; i<=n; i++)
              fatt = fatt*i;
         return fatt;
   }

  main() {
   int risultato, n = 4 ;
   risultato = fattoriale(n);
   cout<<“fattoriale(“<<n<<”) = “<<risultato<<endl ;
  }
                                            Stampa
                                            fattoriale(4) = 24
Programmazione - Paolo Valente, 2008/2009
Esercizio
• Provare a realizzare il calcolo del fattoriale
  mediante una funzione senza utilizzare la
  precedente variabile ausiliaria




Programmazione - Paolo Valente, 2008/2009
Esempio 2bis
  int fattoriale (int n)
     {
         if (n == 0) return 1;
         int fatt = n;                        // senza variabile ausiliaria i
         for (n--; n > 0; n--)
               fatt = fatt*n;
         return(fatt);
                                   Anche se il parametro formale n viene modificato,
   }                               la variabile n definita nel main non viene alterata!
                                   E’ il suo valore (4) che viene passato alla funzione.
  main() {
   int risultato, n = 4 ;                  Stampa
   risultato = fattoriale(n);              fattoriale(4) = 24
   cout<<“fattoriale(“<<n<<”) = “<<risultato<<endl ;
  }
Programmazione - Paolo Valente, 2008/2009
Commenti al passaggio per valore
• E’ sicuro: le variabili del chiamante e del chiamato sono
  completamente disaccoppiate
• Consente di ragionare per componenti e servizi: la
  struttura interna dei singoli componenti è irrilevante
  (la funzione può anche modificare i parametri ricevuti
  senza che ciò abbia impatto sul chiamante)

• LIMITI
   – impedisce a priori di scrivere funzioni che abbiano
     come scopo proprio quello di modificare i dati
     passati dall’ambiente chiamante
   – come vedremo può essere costoso per dati di
     grosse dimensioni
Programmazione - Paolo Valente, 2008/2009
Domanda
• Se un parametro formale è dichiarato di tipo
  const, lo si può poi modificare all'interno della
  funzione?
• Esempio:
  int fun(const int j)
  {
       j++ ;
  }




Programmazione - Paolo Valente, 2008/2009
Risposta
• Ovviamente no
• Il parametro è inizializzato all'atto della chiamata
  della funzione, e da quel momento non potrà più
  essere modificato
• Quindi:
  int fun(const int j)
  {
       j++ ; // ERRATO !! NON VERRA' COMPILATO
  }


Programmazione - Paolo Valente, 2008/2009
Nota 1/2
• Abbiamo visto la modifica di un parametro formale
  variabile all'intero di una funzione solo per capire che
  la cosa si può fare, e che tale parametro è
  perfettamente equivalente ad una variabile locale
• Tuttavia, è fondamentale avere presente che
      – In generale è una cattiva abitudine modificare i
        parametri formali per utilizzarli come variabili
        ausiliarie
         o Poca leggibilità

         o Rischioso nel caso di parametri passati per

           riferimento (che vedremo nelle prossime lezioni)

Programmazione - Paolo Valente, 2008/2009
Nota 2/2
• L'unico caso in cui è necessario ed appropriato
  modificare i parametri formali è quando tali parametri
  sono intesi come parametri di uscita, ossia
  parametri in cui devono essere memorizzati valori che
  saranno poi utilizzati da chi ha invocato la funzione
• Questo non può però accadere nel caso di passaggio
  per valore, perché i parametri formali sono oggetti
  locali alla funzione, e saranno quindi eliminati alla
  terminazione della funzione stessa
• Vedremo invece più avanti come implementare i
  parametri di uscita mediante il passaggio per
  riferimento
Programmazione - Paolo Valente, 2008/2009
Nota conclusiva sui
                       vantaggi delle funzioni
• Testo del programma suddiviso in unità significative
• Testo di ogni unità più breve
    – minore probabilità di errori
    – migliore verificabilità
• Riutilizzo di codice
• Migliore leggibilità
• Supporto allo sviluppo top-down del software
    – Si può progettare prima quello che c'è da fare in generale,
      e poi si può realizzare ogni singola parte

 Programmazione - Paolo Valente, 2008/2009

More Related Content

What's hot

15 - Programmazione: Algoritmi
15 - Programmazione: Algoritmi15 - Programmazione: Algoritmi
15 - Programmazione: AlgoritmiMajong DevJfu
 
Lezione 21 (2 maggio 2012)
Lezione 21 (2 maggio 2012)Lezione 21 (2 maggio 2012)
Lezione 21 (2 maggio 2012)STELITANO
 
Lezione 12 (28 marzo 2012)
Lezione 12 (28 marzo 2012)Lezione 12 (28 marzo 2012)
Lezione 12 (28 marzo 2012)STELITANO
 
Corso Iphone in 48h
Corso Iphone in 48hCorso Iphone in 48h
Corso Iphone in 48h
FLT.lab
 
Lezione 11 (26 marzo 2012)
Lezione 11 (26 marzo 2012)Lezione 11 (26 marzo 2012)
Lezione 11 (26 marzo 2012)STELITANO
 
Lezione 12 (28 marzo 2012)
Lezione 12 (28 marzo 2012)Lezione 12 (28 marzo 2012)
Lezione 12 (28 marzo 2012)STELITANO
 
Riepilogo Java C/C++
Riepilogo Java C/C++Riepilogo Java C/C++
Riepilogo Java C/C++
Pasquale Paola
 
Lezione 5 (7 marzo 2012)
Lezione 5 (7 marzo 2012)Lezione 5 (7 marzo 2012)
Lezione 5 (7 marzo 2012)STELITANO
 
JavaScript Object Oriented
JavaScript Object OrientedJavaScript Object Oriented
JavaScript Object Oriented
Manuel Scapolan
 
9 Altre Istruzioni Di I O
9   Altre Istruzioni Di I O9   Altre Istruzioni Di I O
9 Altre Istruzioni Di I Oguest60e9511
 
Introduzione a JavaScript
Introduzione a JavaScriptIntroduzione a JavaScript
Introduzione a JavaScript
Giovanni Buffa
 
09 - Programmazione: Ingegneria del Codice
09 - Programmazione: Ingegneria del Codice09 - Programmazione: Ingegneria del Codice
09 - Programmazione: Ingegneria del CodiceMajong DevJfu
 
Corso c++
Corso c++Corso c++
Corso c++
Antonio Furone
 
Vogliamo programmatori stupidi e pigri!
Vogliamo programmatori stupidi e pigri!Vogliamo programmatori stupidi e pigri!
Vogliamo programmatori stupidi e pigri!
Marcello Missiroli
 
Flow chart
Flow chartFlow chart
Flow chart
orestJump
 
Lezione 16 (2 aprile 2012)
Lezione 16 (2 aprile 2012)Lezione 16 (2 aprile 2012)
Lezione 16 (2 aprile 2012)STELITANO
 
Esercitazione 1 (27 febbraio 2012)
Esercitazione 1 (27 febbraio 2012)Esercitazione 1 (27 febbraio 2012)
Esercitazione 1 (27 febbraio 2012)STELITANO
 
Python - Primi passi
Python - Primi passi Python - Primi passi
Python - Primi passi
orestJump
 

What's hot (20)

15 - Programmazione: Algoritmi
15 - Programmazione: Algoritmi15 - Programmazione: Algoritmi
15 - Programmazione: Algoritmi
 
Lezione 21 (2 maggio 2012)
Lezione 21 (2 maggio 2012)Lezione 21 (2 maggio 2012)
Lezione 21 (2 maggio 2012)
 
Lezione 12 (28 marzo 2012)
Lezione 12 (28 marzo 2012)Lezione 12 (28 marzo 2012)
Lezione 12 (28 marzo 2012)
 
Corso Iphone in 48h
Corso Iphone in 48hCorso Iphone in 48h
Corso Iphone in 48h
 
Lezione 11 (26 marzo 2012)
Lezione 11 (26 marzo 2012)Lezione 11 (26 marzo 2012)
Lezione 11 (26 marzo 2012)
 
Lezione 12 (28 marzo 2012)
Lezione 12 (28 marzo 2012)Lezione 12 (28 marzo 2012)
Lezione 12 (28 marzo 2012)
 
Riepilogo Java C/C++
Riepilogo Java C/C++Riepilogo Java C/C++
Riepilogo Java C/C++
 
Lezione 5 (7 marzo 2012)
Lezione 5 (7 marzo 2012)Lezione 5 (7 marzo 2012)
Lezione 5 (7 marzo 2012)
 
JavaScript Object Oriented
JavaScript Object OrientedJavaScript Object Oriented
JavaScript Object Oriented
 
9 Altre Istruzioni Di I O
9   Altre Istruzioni Di I O9   Altre Istruzioni Di I O
9 Altre Istruzioni Di I O
 
Introduzione a JavaScript
Introduzione a JavaScriptIntroduzione a JavaScript
Introduzione a JavaScript
 
09 - Programmazione: Ingegneria del Codice
09 - Programmazione: Ingegneria del Codice09 - Programmazione: Ingegneria del Codice
09 - Programmazione: Ingegneria del Codice
 
Corso c++
Corso c++Corso c++
Corso c++
 
Vogliamo programmatori stupidi e pigri!
Vogliamo programmatori stupidi e pigri!Vogliamo programmatori stupidi e pigri!
Vogliamo programmatori stupidi e pigri!
 
Flow chart
Flow chartFlow chart
Flow chart
 
Lezione 16 (2 aprile 2012)
Lezione 16 (2 aprile 2012)Lezione 16 (2 aprile 2012)
Lezione 16 (2 aprile 2012)
 
Pillole di C++
Pillole di C++Pillole di C++
Pillole di C++
 
Esercitazione 1 (27 febbraio 2012)
Esercitazione 1 (27 febbraio 2012)Esercitazione 1 (27 febbraio 2012)
Esercitazione 1 (27 febbraio 2012)
 
7 Sottoprogrammi
7   Sottoprogrammi7   Sottoprogrammi
7 Sottoprogrammi
 
Python - Primi passi
Python - Primi passi Python - Primi passi
Python - Primi passi
 

Viewers also liked

17 - Programmazione: Introduzione alle liste
17 - Programmazione: Introduzione alle liste17 - Programmazione: Introduzione alle liste
17 - Programmazione: Introduzione alle listeMajong DevJfu
 
Architettura dei Calcolatori 06 Elementi Architetturali Di Base
Architettura dei Calcolatori 06 Elementi Architetturali Di BaseArchitettura dei Calcolatori 06 Elementi Architetturali Di Base
Architettura dei Calcolatori 06 Elementi Architetturali Di BaseMajong DevJfu
 
Lezione1 Linguaggio C
Lezione1 Linguaggio CLezione1 Linguaggio C
2 sistemi informativi d azienda
2 sistemi informativi d azienda2 sistemi informativi d azienda
2 sistemi informativi d azienda
Majong DevJfu
 
esercizio sigda n 11
esercizio sigda n 11esercizio sigda n 11
esercizio sigda n 11Majong DevJfu
 
5 Trasporto Affidabile Teoria
5 Trasporto Affidabile Teoria5 Trasporto Affidabile Teoria
5 Trasporto Affidabile TeoriaMajong DevJfu
 
Sistemi Operativi: Struttura - Lezione 04
Sistemi Operativi: Struttura - Lezione 04Sistemi Operativi: Struttura - Lezione 04
Sistemi Operativi: Struttura - Lezione 04Majong DevJfu
 
Sistemi Operativi: Meccanismi - Lezione 03
Sistemi Operativi: Meccanismi - Lezione 03Sistemi Operativi: Meccanismi - Lezione 03
Sistemi Operativi: Meccanismi - Lezione 03Majong DevJfu
 
4 Livello Ip Parte1 Color
4 Livello Ip Parte1 Color4 Livello Ip Parte1 Color
4 Livello Ip Parte1 ColorMajong DevJfu
 
Linguaggi Formali e Compilazione: Frontend
Linguaggi Formali e Compilazione: FrontendLinguaggi Formali e Compilazione: Frontend
Linguaggi Formali e Compilazione: FrontendMajong DevJfu
 
Architettura dei Calcolatori Subroutines80x86
Architettura dei Calcolatori Subroutines80x86Architettura dei Calcolatori Subroutines80x86
Architettura dei Calcolatori Subroutines80x86Majong DevJfu
 
Traffic Shaping Su Linux
Traffic Shaping Su LinuxTraffic Shaping Su Linux
Traffic Shaping Su LinuxMajong DevJfu
 
Sistemi Operativi: Struttura avanzata - Lezione 05
Sistemi Operativi: Struttura avanzata - Lezione 05Sistemi Operativi: Struttura avanzata - Lezione 05
Sistemi Operativi: Struttura avanzata - Lezione 05Majong DevJfu
 
Sistemi Operativi: Processi - Lezione 07
Sistemi Operativi: Processi - Lezione 07Sistemi Operativi: Processi - Lezione 07
Sistemi Operativi: Processi - Lezione 07Majong DevJfu
 

Viewers also liked (20)

17 - Programmazione: Introduzione alle liste
17 - Programmazione: Introduzione alle liste17 - Programmazione: Introduzione alle liste
17 - Programmazione: Introduzione alle liste
 
Architettura dei Calcolatori 06 Elementi Architetturali Di Base
Architettura dei Calcolatori 06 Elementi Architetturali Di BaseArchitettura dei Calcolatori 06 Elementi Architetturali Di Base
Architettura dei Calcolatori 06 Elementi Architetturali Di Base
 
Lezione1 Linguaggio C
Lezione1 Linguaggio CLezione1 Linguaggio C
Lezione1 Linguaggio C
 
2 sistemi informativi d azienda
2 sistemi informativi d azienda2 sistemi informativi d azienda
2 sistemi informativi d azienda
 
esercizio sigda n 11
esercizio sigda n 11esercizio sigda n 11
esercizio sigda n 11
 
E6 Concorre
E6 ConcorreE6 Concorre
E6 Concorre
 
5 Trasporto Affidabile Teoria
5 Trasporto Affidabile Teoria5 Trasporto Affidabile Teoria
5 Trasporto Affidabile Teoria
 
Sistemi Operativi: Struttura - Lezione 04
Sistemi Operativi: Struttura - Lezione 04Sistemi Operativi: Struttura - Lezione 04
Sistemi Operativi: Struttura - Lezione 04
 
Sistemi Operativi: Meccanismi - Lezione 03
Sistemi Operativi: Meccanismi - Lezione 03Sistemi Operativi: Meccanismi - Lezione 03
Sistemi Operativi: Meccanismi - Lezione 03
 
3 H2 N Parte3
3 H2 N Parte33 H2 N Parte3
3 H2 N Parte3
 
4 Livello Ip Parte1 Color
4 Livello Ip Parte1 Color4 Livello Ip Parte1 Color
4 Livello Ip Parte1 Color
 
8 Www2009 Parte1
8 Www2009 Parte18 Www2009 Parte1
8 Www2009 Parte1
 
Linguaggi Formali e Compilazione: Frontend
Linguaggi Formali e Compilazione: FrontendLinguaggi Formali e Compilazione: Frontend
Linguaggi Formali e Compilazione: Frontend
 
Architettura dei Calcolatori Subroutines80x86
Architettura dei Calcolatori Subroutines80x86Architettura dei Calcolatori Subroutines80x86
Architettura dei Calcolatori Subroutines80x86
 
Traffic Shaping Su Linux
Traffic Shaping Su LinuxTraffic Shaping Su Linux
Traffic Shaping Su Linux
 
9 Ftp Telnet Email
9 Ftp Telnet Email9 Ftp Telnet Email
9 Ftp Telnet Email
 
Sistemi Operativi: Struttura avanzata - Lezione 05
Sistemi Operativi: Struttura avanzata - Lezione 05Sistemi Operativi: Struttura avanzata - Lezione 05
Sistemi Operativi: Struttura avanzata - Lezione 05
 
6 Dns Parte2
6 Dns Parte26 Dns Parte2
6 Dns Parte2
 
Sistemi Operativi: Processi - Lezione 07
Sistemi Operativi: Processi - Lezione 07Sistemi Operativi: Processi - Lezione 07
Sistemi Operativi: Processi - Lezione 07
 
esercizio sigda n 8
esercizio sigda n 8esercizio sigda n 8
esercizio sigda n 8
 

Similar to 05 - Programmazione: Funzioni

Laboratorio Programmazione: Operatori logici
Laboratorio Programmazione: Operatori logiciLaboratorio Programmazione: Operatori logici
Laboratorio Programmazione: Operatori logiciMajong DevJfu
 
5 Strutture Iterative
5   Strutture Iterative5   Strutture Iterative
5 Strutture Iterativeguest60e9511
 
Laboratorio Programmazione: In - Out variabili
Laboratorio Programmazione: In - Out variabiliLaboratorio Programmazione: In - Out variabili
Laboratorio Programmazione: In - Out variabiliMajong DevJfu
 
Lezione 6 (12 marzo 2012)
Lezione 6 (12 marzo 2012)Lezione 6 (12 marzo 2012)
Lezione 6 (12 marzo 2012)STELITANO
 
Lezione 3 (29 febbraio 2012)
Lezione 3 (29 febbraio 2012)Lezione 3 (29 febbraio 2012)
Lezione 3 (29 febbraio 2012)STELITANO
 
Ecdl modulo 1 -Fondamenti
Ecdl modulo 1 -FondamentiEcdl modulo 1 -Fondamenti
Ecdl modulo 1 -FondamentiAngela Cristina
 
Caratteristiche del linguaggio c
Caratteristiche del linguaggio cCaratteristiche del linguaggio c
Caratteristiche del linguaggio cughetta
 
Algoritmi
Algoritmi Algoritmi
Algoritmi
Emilia Calzetta
 
Algorithmist guide II
Algorithmist guide IIAlgorithmist guide II
Algorithmist guide II
Marcello Missiroli
 
Esercitazione 4 (19 marzo 2012)
Esercitazione 4 (19 marzo 2012)Esercitazione 4 (19 marzo 2012)
Esercitazione 4 (19 marzo 2012)STELITANO
 
Laboratorio Programmazione: Overflow e switch
Laboratorio Programmazione: Overflow e switchLaboratorio Programmazione: Overflow e switch
Laboratorio Programmazione: Overflow e switchMajong DevJfu
 
Laboratorio Programmazione: Funzioni
Laboratorio Programmazione: FunzioniLaboratorio Programmazione: Funzioni
Laboratorio Programmazione: FunzioniMajong DevJfu
 
Corso Programmazione Java Base
Corso Programmazione Java BaseCorso Programmazione Java Base
Corso Programmazione Java Base
K-Tech Formazione
 
Le basi di Pytthon 3 - Fondamenti n.1
Le basi di Pytthon 3 - Fondamenti n.1Le basi di Pytthon 3 - Fondamenti n.1
Le basi di Pytthon 3 - Fondamenti n.1
I.S.I.S. "Antonio Serra" - Napoli
 
Soluzione esame b del 13 giugno 2012
Soluzione esame b del 13 giugno 2012Soluzione esame b del 13 giugno 2012
Soluzione esame b del 13 giugno 2012STELITANO
 
Soluzione esame a del 13 giugno 2012
Soluzione esame a del 13 giugno 2012Soluzione esame a del 13 giugno 2012
Soluzione esame a del 13 giugno 2012STELITANO
 
Algoritmi e Programmazione Avanzata - Esercizi propedeutici
Algoritmi e Programmazione Avanzata - Esercizi propedeuticiAlgoritmi e Programmazione Avanzata - Esercizi propedeutici
Algoritmi e Programmazione Avanzata - Esercizi propedeutici
Sergio Porcu
 
4 Strutture Condizionali
4   Strutture Condizionali4   Strutture Condizionali
4 Strutture Condizionaliguest60e9511
 

Similar to 05 - Programmazione: Funzioni (20)

Laboratorio Programmazione: Operatori logici
Laboratorio Programmazione: Operatori logiciLaboratorio Programmazione: Operatori logici
Laboratorio Programmazione: Operatori logici
 
5 Strutture Iterative
5   Strutture Iterative5   Strutture Iterative
5 Strutture Iterative
 
Laboratorio Programmazione: In - Out variabili
Laboratorio Programmazione: In - Out variabiliLaboratorio Programmazione: In - Out variabili
Laboratorio Programmazione: In - Out variabili
 
1 Programmazione
1   Programmazione1   Programmazione
1 Programmazione
 
Lezione 6 (12 marzo 2012)
Lezione 6 (12 marzo 2012)Lezione 6 (12 marzo 2012)
Lezione 6 (12 marzo 2012)
 
Lezione 3 (29 febbraio 2012)
Lezione 3 (29 febbraio 2012)Lezione 3 (29 febbraio 2012)
Lezione 3 (29 febbraio 2012)
 
Ecdl modulo 1 -Fondamenti
Ecdl modulo 1 -FondamentiEcdl modulo 1 -Fondamenti
Ecdl modulo 1 -Fondamenti
 
Caratteristiche del linguaggio c
Caratteristiche del linguaggio cCaratteristiche del linguaggio c
Caratteristiche del linguaggio c
 
Algoritmi
Algoritmi Algoritmi
Algoritmi
 
Algorithmist guide II
Algorithmist guide IIAlgorithmist guide II
Algorithmist guide II
 
Tutorial Matlab 2009
Tutorial Matlab 2009Tutorial Matlab 2009
Tutorial Matlab 2009
 
Esercitazione 4 (19 marzo 2012)
Esercitazione 4 (19 marzo 2012)Esercitazione 4 (19 marzo 2012)
Esercitazione 4 (19 marzo 2012)
 
Laboratorio Programmazione: Overflow e switch
Laboratorio Programmazione: Overflow e switchLaboratorio Programmazione: Overflow e switch
Laboratorio Programmazione: Overflow e switch
 
Laboratorio Programmazione: Funzioni
Laboratorio Programmazione: FunzioniLaboratorio Programmazione: Funzioni
Laboratorio Programmazione: Funzioni
 
Corso Programmazione Java Base
Corso Programmazione Java BaseCorso Programmazione Java Base
Corso Programmazione Java Base
 
Le basi di Pytthon 3 - Fondamenti n.1
Le basi di Pytthon 3 - Fondamenti n.1Le basi di Pytthon 3 - Fondamenti n.1
Le basi di Pytthon 3 - Fondamenti n.1
 
Soluzione esame b del 13 giugno 2012
Soluzione esame b del 13 giugno 2012Soluzione esame b del 13 giugno 2012
Soluzione esame b del 13 giugno 2012
 
Soluzione esame a del 13 giugno 2012
Soluzione esame a del 13 giugno 2012Soluzione esame a del 13 giugno 2012
Soluzione esame a del 13 giugno 2012
 
Algoritmi e Programmazione Avanzata - Esercizi propedeutici
Algoritmi e Programmazione Avanzata - Esercizi propedeuticiAlgoritmi e Programmazione Avanzata - Esercizi propedeutici
Algoritmi e Programmazione Avanzata - Esercizi propedeutici
 
4 Strutture Condizionali
4   Strutture Condizionali4   Strutture Condizionali
4 Strutture Condizionali
 

More from Majong DevJfu

9 - Architetture Software - SOA Cloud
9 - Architetture Software - SOA Cloud9 - Architetture Software - SOA Cloud
9 - Architetture Software - SOA CloudMajong DevJfu
 
8 - Architetture Software - Architecture centric processes
8 - Architetture Software - Architecture centric processes8 - Architetture Software - Architecture centric processes
8 - Architetture Software - Architecture centric processesMajong DevJfu
 
7 - Architetture Software - Software product line
7 - Architetture Software - Software product line7 - Architetture Software - Software product line
7 - Architetture Software - Software product lineMajong DevJfu
 
6 - Architetture Software - Model transformation
6 - Architetture Software - Model transformation6 - Architetture Software - Model transformation
6 - Architetture Software - Model transformationMajong DevJfu
 
5 - Architetture Software - Metamodelling and the Model Driven Architecture
5 - Architetture Software - Metamodelling and the Model Driven Architecture5 - Architetture Software - Metamodelling and the Model Driven Architecture
5 - Architetture Software - Metamodelling and the Model Driven ArchitectureMajong DevJfu
 
4 - Architetture Software - Architecture Portfolio
4 - Architetture Software - Architecture Portfolio4 - Architetture Software - Architecture Portfolio
4 - Architetture Software - Architecture PortfolioMajong DevJfu
 
3 - Architetture Software - Architectural styles
3 - Architetture Software - Architectural styles3 - Architetture Software - Architectural styles
3 - Architetture Software - Architectural stylesMajong DevJfu
 
2 - Architetture Software - Software architecture
2 - Architetture Software - Software architecture2 - Architetture Software - Software architecture
2 - Architetture Software - Software architectureMajong DevJfu
 
1 - Architetture Software - Software as a product
1 - Architetture Software - Software as a product1 - Architetture Software - Software as a product
1 - Architetture Software - Software as a productMajong DevJfu
 
10 - Architetture Software - More architectural styles
10 - Architetture Software - More architectural styles10 - Architetture Software - More architectural styles
10 - Architetture Software - More architectural stylesMajong DevJfu
 

More from Majong DevJfu (20)

9 - Architetture Software - SOA Cloud
9 - Architetture Software - SOA Cloud9 - Architetture Software - SOA Cloud
9 - Architetture Software - SOA Cloud
 
8 - Architetture Software - Architecture centric processes
8 - Architetture Software - Architecture centric processes8 - Architetture Software - Architecture centric processes
8 - Architetture Software - Architecture centric processes
 
7 - Architetture Software - Software product line
7 - Architetture Software - Software product line7 - Architetture Software - Software product line
7 - Architetture Software - Software product line
 
6 - Architetture Software - Model transformation
6 - Architetture Software - Model transformation6 - Architetture Software - Model transformation
6 - Architetture Software - Model transformation
 
5 - Architetture Software - Metamodelling and the Model Driven Architecture
5 - Architetture Software - Metamodelling and the Model Driven Architecture5 - Architetture Software - Metamodelling and the Model Driven Architecture
5 - Architetture Software - Metamodelling and the Model Driven Architecture
 
4 - Architetture Software - Architecture Portfolio
4 - Architetture Software - Architecture Portfolio4 - Architetture Software - Architecture Portfolio
4 - Architetture Software - Architecture Portfolio
 
3 - Architetture Software - Architectural styles
3 - Architetture Software - Architectural styles3 - Architetture Software - Architectural styles
3 - Architetture Software - Architectural styles
 
2 - Architetture Software - Software architecture
2 - Architetture Software - Software architecture2 - Architetture Software - Software architecture
2 - Architetture Software - Software architecture
 
1 - Architetture Software - Software as a product
1 - Architetture Software - Software as a product1 - Architetture Software - Software as a product
1 - Architetture Software - Software as a product
 
10 - Architetture Software - More architectural styles
10 - Architetture Software - More architectural styles10 - Architetture Software - More architectural styles
10 - Architetture Software - More architectural styles
 
Uml3
Uml3Uml3
Uml3
 
Uml2
Uml2Uml2
Uml2
 
6
66
6
 
5
55
5
 
4 (uml basic)
4 (uml basic)4 (uml basic)
4 (uml basic)
 
3
33
3
 
2
22
2
 
1
11
1
 
Tmd template-sand
Tmd template-sandTmd template-sand
Tmd template-sand
 
26 standards
26 standards26 standards
26 standards
 

05 - Programmazione: Funzioni

  • 1. Funzioni Parte I Definizione, Dichiarazione o Prototipo, Chiamata
  • 2. Blocco • Sequenza di definizioni e istruzioni racchiuse tra parentesi graffe { <dichiarazione1 o istruzione1> <dichiarazione2 o istruzione2> ... } • In C, parte dichiarativa ed esecutiva devono essere separate: { <dichiarazioni> <istruzioni> ... } Programmazione - Paolo Valente, 2008/2009
  • 3. Blocco ed istruzione composta • Per semplicità in precedenza abbiamo definito l'istruzione composta come un caso particolare di blocco in cui c'erano solo istruzioni – In verità un'istruzione composta si esprime esattamente mediante un blocco – Quindi si possono inserire dichiarazioni anche in un'istruzione composta • Inoltre con i blocchi non si esprimono solo le istruzioni composte, ma anche ad esempio i corpi delle funzioni, come vedremo a breve ... Programmazione - Paolo Valente, 2008/2009
  • 4. Utilità delle funzioni • Per evidenziare l'utilità delle funzioni, scriviamo 1) un programma che legga in ingresso un numero intero non negativo e dica all'utente se il numero è primo (o altrimenti non stampi nulla) 2) un programma che legga in ingresso due numeri interi non negativi e, se e solo se sono entrambi primi, dica all'utente se si tratta di due numeri primi gemelli (ossia che differiscono esattamente di due unità l'uno dall'altro) Es.: 5 e 7 sono primi gemelli Cominciamo dal primo programma • Programmazione - Paolo Valente, 2008/2009
  • 5. Programma 1 (prime idee) • Un numero è primo se è divisibile solo per 1 e per se stesso. Quindi, occorre provare a dividere N per tutti i numeri 2≤ i ≤ N-1. Se nessun numero i risulta essere un divisore di N, allora N è primo. Funziona? Sì, ma si può fare meglio • IDEA 1: Poiché i numeri pari non sono primi, eliminiamo subito la possibilità che N sia pari • IDEA 2: Non c’è bisogno di provare tutti i numeri fino a N-1, ma è sufficiente provare a dividere N per tutti i numeri dispari 3≤ i ≤ (N/2): se nessun numero i risulta essere un divisore di N, allora N è primo • IDEA 3: Non c’è bisogno di provare tutti i numeri fino a N/2, ma è sufficiente provare a dividere N per tutti i numeri dispari 3≤ i ≤ √N: se nessun numero i risulta essere un divisore di N, allora N è primo Programmazione - Paolo Valente, 2008/2009
  • 6. Programma 1 (Algoritmo) • Se N è 1, 2 o 3, allora senz’altro N è un numero primo • Altrimenti, se è un numero pari, certamente N non è primo • Se così non è (quindi se N è dispari e >3), occorre tentare tutti i possibili divisori dispari da 3 in avanti, fino a static_cast<int>(sqrt(N)) – Ove sqrt(N) è una funzione che ritorna √N, mentre l'espressione static_cast<int>(sqrt(N)) è uguale al più grande numero intero non maggiore di √N – Nota: ci sta bene utilizzare la parte intera di sqrt(N) perché il potenziale divisore sarà senz'altro un numero intero Programmazione - Paolo Valente, 2008/2009
  • 7. Programma 1 (Rappresentazione informazioni) • Variabile per contenere il numero: int n • Può tornare poi utile una variabile int max_div che contenga la parte intera della radice quadrata del numero – Serve poi una variabile ausiliaria (int i) come indice per andare da 3 a max_div • Per utilizzare la funzione sqrt() occorre: – includere anche <cmath> (<math.h> in C) Es.: #include <iostream> #include <cmath> – aggiungere l'opzione -lm nell'invocazione del g++ Es.: g++ -lm nomefile.cc Programmazione - Paolo Valente, 2008/2009
  • 8. Programma 1 main() { int max_div, n ; cin>>n ; if (n>=1 && n<=3) { cout<<”primo”<<endl ; return ; } if (n%2==0) return; /* no perché numeri pari */ max_div = static_cast<int>(sqrt(n)); for(int i=3; i<=max_div; i=i+2) if (n%i==0) return ; /* no, perché è stato trovato un divisore */ cout<<”primo”<<endl ; } Programmazione - Paolo Valente, 2008/2009
  • 9. Secondo programma • Veniamo ora al secondo programma, che ricordiamo era: Un programma che legge in ingresso due numeri • interi non negativi e, se e solo se sono entrambi primi, comunica all'utente se si tratta di due numeri primi gemelli (ossia che differiscono esattamente di due unità l'uno dall'altro) Riutilizzando le righe di codice già scritte, potremmo • scrivere ad esempio: Programmazione - Paolo Valente, 2008/2009
  • 10. Programma 2 1/2 main() { int n1, n2 ; cin>>n1>>n2 ; int max_div; bool n1_is_prime = false, n2_is_prime = false ; if (n1>=1 && n1<=3) n1_is_prime = true ; else if (n1%2 != 0) { int i; max_div = static_cast<int>(sqrt(n1)); for(i=3; i<=max_div; i=i+2) if (n1%i==0) break ; if (i > max_div) n1_is_prime=true ; } Programmazione - Paolo Valente, 2008/2009
  • 11. Programma 2 2/2 if (n2>=1 && n2<=3) n2_is_prime = true ; else if (n2%2 != 0) { int i ; max_div = static_cast<int>(sqrt(n2)); for(i=3; i<=max_div; i=i+2) if (n2%i==0) break ; if (i > max_div) n2_is_prime=true ; } if (n1_is_prime && n2_is_prime) if (n1 == n2 – 2 || n2 == n1 – 2) cout<<”n1 ed n2 sono due primi gemelli”<<endl ; } Programmazione - Paolo Valente, 2008/2009
  • 12. Considerazioni • Quanto è leggibile il programma? – Non molto • Come mai? • Fondamentalmente perché c'è codice abbastanza lungo ripetuto due volte • Quale sarebbe stato il livello di leggibilità se avessimo avuto a disposizione una funzione is_prime() a cui passavamo come argomento un numero e ci diceva se era primo? Programmazione - Paolo Valente, 2008/2009
  • 13. Programma 2 Altra versione main() { int n1, n2 ; cin>>n1>>n2 ; if (is_prime(n1) && is_prime(n2)) if (n1 == n2 – 2 || n2 == n1 – 2) cout<<”n1 ed n2 sono due primi gemelli”<<endl ; } • Molto più breve, leggibile e facile da capire • Non contiene codice duplicato • Per arrivare a questo risultato dobbiamo imparare a definire ed utilizzare le funzioni ... Programmazione - Paolo Valente, 2008/2009
  • 14. Indice Lezioni Linguaggio C/C++ √ Tipi di dato primitivi (focus su int) √ Dichiarazioni e Definizioni √ Espressioni √ Istruzioni • Funzioni Programmazione - Paolo Valente, 2008/2009
  • 15. Concetto di funzione • L’astrazione di funzione è presente in tutti i linguaggi di programmazione di alto livello • Una funzione è un componente software che rispecchia l'astrazione matematica di funzione: f : A × B × ... × Q → S – molti ingressi possibili (corrispondenti ai valori su cui operare) – una sola uscita (corrispondente al risultato o valore di ritorno) • Per calcolare il valore di ritorno della funzione dovranno essere eseguite una serie di istruzioni – In C/C++ tali istruzioni sono specificate mediante un blocco, a cui ci si riferisce tipicamente come il corpo della funzione Programmazione - Paolo Valente, 2008/2009
  • 16. Procedura • Altri linguaggi (ma non il C/C++!) introducono anche l’astrazione di procedura, che cattura la sola astrazione dell'esecuzione di un insieme di azioni, senza ritornare risultati • Comunque, come vedremo è IMMEDIATO DA EMULARE IN C/C++ mediante funzioni dal valore di ritorno vuoto Programmazione - Paolo Valente, 2008/2009
  • 17. I tre elementi fondamentali per comprendere le funzioni • Definizione e dichiarazione della funzione • Uso della funzione (chiamata) • Esecuzione della funzione (record di attivazione) – Si vedrà in seguito Programmazione - Paolo Valente, 2008/2009
  • 18. Definizione di funzione • Una definizione di funzione è costituita da una intestazione e da un corpo, definito mediante un blocco Programmazione - Paolo Valente, 2008/2009
  • 19. Esempi di intestazioni int fattoriale (int n) Nome della Tipo Lista dei parametri funzione risultato formali int somma3 (int x, int y, int z) Tipo Nome della Lista dei parametri risultato funzione formali void stampa_n_volte (int n) Tipo Nome della funzione Lista dei parametri risultato formali void stampa_2_volte (void) Lista dei parametri formali vuota Nome della Tipo (void può essere omesso). funzione risultato LE PARENTESI SERVONO SEMPRE Programmazione - Paolo Valente, 2008/2009
  • 20. Sintassi definizione di funzione • Come già detto, una definizione di funzione è costituita da una intestazione e da un corpo, definito mediante un blocco <def-funzione> ::= <intestazione-funzione> <blocco> <intestazione-funzione> ::= <nomeTipo> <nomeFunzione> ( <lista-parametri> ) <lista-parametri> ::= void | <def-parametro> { , <def-parametro> } <def-parametro> ::= <nomeTipo> <identificatore> Programmazione - Paolo Valente, 2008/2009
  • 21. Definizione di funzione (cont.) L’intestazione specifica nell’ordine: • Tipo del risultato (void se non c’è risultato); corrisponde alla procedura di altri linguaggi • Nome della funzione • Lista dei parametri formali (in ingresso) – void se la lista è vuota (non ci sono parametri) o in questo caso può anche essere omessa la lista stessa – una sequenza di definizioni di parametri, se la lista non è vuota Programmazione - Paolo Valente, 2008/2009
  • 22. Definizione di funzione (cont.) Il corpo della funzione è costituito da un blocco: • Delimitato da parentesi graffe { } • Dichiarazione/definizione di variabili locali al blocco di funzione • Lista di istruzioni Programmazione - Paolo Valente, 2008/2009
  • 23. I tre elementi fondamentali per comprendere le funzioni • Definizione e dichiarazione della funzione • Uso della funzione (chiamata) • Esecuzione della funzione (record di attivazione) Programmazione - Paolo Valente, 2008/2009
  • 24. Chiamata di funzione • Una chiamata di funzione è costituita dal nome della funzione e dalla lista dei parametri attuali tra parentesi tonde: <chiam-funzione> ::= <nomeFunzione> ( <lista-parametri-attuali> ) • La chiamata di una funzione è una espressione • Un parametro attuale è una espressione il cui risultato è il valore da assegnare al parametro formale che si trova in quella posizione – Ci torneremo sopra a breve Programmazione - Paolo Valente, 2008/2009
  • 25. Esempio void fun(int a) { Definizione cout<<a<<endl ; } int main() Invocazione { fun(3) ; } Programmazione - Paolo Valente, 2008/2009
  • 26. Proviamo ... • ... a scrivere, compilare ed eseguire un programma in cui – Si definisce una funzione di nome fun, che ● non prende alcun parametro in ingresso ● non ritorna alcun valore ● Stampa sullo schermo un messaggio ● Si invoca tale funzione all'interno della funzione main e si esce Programmazione - Paolo Valente, 2008/2009
  • 27. Soluzione void fun() { cout<<quot;Saluti dalla funzione funquot;<<endl ; } main() { fun() ; } Programmazione - Paolo Valente, 2008/2009
  • 28. Lista dei parametri formali e attuali • Lista parametri formali: argomenti dichiarati nella definizione di funzione Devono essere variabili o costanti con nome • Lista parametri attuali: argomenti inseriti al momento della chiamata di funzione Espressioni separate da virgole, ove ciascuna espressione puà essere una: – costante – variabile – espressione aritmetica o logica – … Programmazione - Paolo Valente, 2008/2009
  • 29. Dinamica parametri formali e attuali • La corrispondenza tra parametri formali e attuali è posizionale, con in più il controllo di tipo. Si presume che la lista dei parametri formali e la lista dei parametri attuali abbiano lo stesso numero e tipo di elementi (l'uso della conversione di tipo si vedrà in seguito) • La corrispondenza tra i nomi dei parametri attuali e formali non ha nessuna importanza. Gli eventuali nomi di variabili passate come parametri attuali possono essere gli stessi o diversi. Conta solo la posizione all'interno della chiamata • Non appena parte l'esecuzione di una funzione, ciascuno dei parametri formali viene definito (come variabile locale alla funzione) ed inizializzato al valore del corrispondente parametro attuale Programmazione - Paolo Valente, 2008/2009
  • 30. Collocazione definizioni di funzione Una funzione non può essere definita all'interno di un'altra funzione int main() { void fun() { cout<<quot;Saluti dalla funzione funquot;<<endl ; } fun() ; return 0 ; } Programmazione - Paolo Valente, 2008/2009
  • 31. Ancora sui parametri formali 1/2 Un parametro formale non è altro che una variabile locale alla funzione Definizioni (quasi) equivalenti di una variabile locale i void fun(int i) void fun() { { Istruzione legale i++ ; int i ; cout<<i ; i++ ; } cout<<i ; } Programmazione - Paolo Valente, 2008/2009
  • 32. Ancora sui parametri formali 2/2 Unica differenza (ma molto importante) i è inizializzata col valore del parametro attuale void fun() { void fun(int i) int i ; { i++ ; i++ ; cout<<i ; cout<<i ; } } i ha un valore iniziale casuale Programmazione - Paolo Valente, 2008/2009
  • 33. Istruzione return 1/2 • Viene usata per far terminare l'esecuzione della funzione e far proseguire il programma dall'istruzione successiva a quella con cui la funzione è stata invocata, ossia per restituire il controllo alla funzione chiamante, e, se la funzione ha tipo di ritorno diverso da void, restituire il valore calcolato dalla funzione, ossia il risultato della funzione • Sintassi nel caso di funzioni con tipo di ritorno diverso da void: return (<espressione>) ; oppure semplicemente return <espressione> ; <espressione> deve essere del tipo di ritorno specificato nell’intestazione della funzione • Sintassi nel caso di funzioni con tipo di ritorno void: return ; Programmazione - Paolo Valente, 2008/2009
  • 34. Istruzione return 2/2 • Eventuali istruzioni della funzione successive all’esecuzione del return non saranno eseguite! • Nel caso della funzione main l’esecuzione dell'istruzione return fa uscire dall'intero programma • Una funzione con tipo di ritorno void può terminare o quando viene eseguita l'istruzione return o quando l'esecuzione giunge in fondo alla funzione • Al contrario, una funzione con tipo di ritorno diverso da void deve sempre terminare con una istruzione return, perché bisogna specificare il valore di ritorno Programmazione - Paolo Valente, 2008/2009
  • 35. I tre elementi fondamentali per comprendere le funzioni • Definizione e dichiarazione della funzione • Uso della funzione (chiamata) • Esecuzione della funzione (record di attivazione) Programmazione - Paolo Valente, 2008/2009
  • 36. Esecuzione di istruzioni e valore di ritorno • La chiamata di una funzione è una espressione • Due casi: – Funzioni void: la chiamata di funzione va considerata solamente come l'invocazione di un insieme di istruzioni (procedura) – Funzioni che ritornano un valore: la chiamata di funzio- ne va considerata come un'espressione il cui valore di ritorno (calcolato eseguendo le istruzioni della funzione) è di tipo uguale al tipo di ritorno della funzione, e può essere utilizzato come fattore all'interno di espressioni composte Esempio: Supponendo che fun() ritorni un valore di tipo int: int b = fun(a) + 1 ; Programmazione - Paolo Valente, 2008/2009
  • 38. Anatomia funzione fattoriale int fattoriale (int n) INTESTAZIONE Nome della Lista dei parametri Tipo funzione ritorno formali { int fatt; Definizioni locali alla funzione Restituzione del if (n==0) return 1; CORPO valore for (int i=1; i<=n; i++) fatt = fatt*i; Restituzione del return fatt; valore } Programmazione - Paolo Valente, 2008/2009
  • 39. Progetto di una funzione • Scegliere un nome significativo per la funzione • La funzione deve ricevere qualche dato dalla funzione chiamante? Se sì, elencare ed identificare tutti i tipi di dato da passare alla funzione (questa è chiamata la lista dei parametri o la lista degli argomenti). Se no, la lista dei parametri è void La funzione deve restituire un dato dalla funzione • chiamante? Se sì, identificare il tipo di dato  corrisponderà al tipo di ritorno della funzione Se no, il tipo della funzione è void Programmazione - Paolo Valente, 2008/2009
  • 40. Dichiarazione della funzione • Nel linguaggio C/C++ si possono utilizzare solo oggetti precedentemente dichiarati • Questo vale anche per le funzioni, che quindi possono essere invocate solo dopo essere state precedentemente dichiarate – Finora abbiamo visto solo definizioni di funzione – Sono in effetti un caso di dichiarazione: quello in cui si definisce anche il corpo della funzione stessa o Comportano l'allocazione di spazio in memoria per le variabili e le istruzioni • Ci sono diverse situazioni in cui è utile o necessario utilizzare una funzione definita altrove o successivamente • Ad esempio, nel caso di ... Programmazione - Paolo Valente, 2008/2009
  • 41. Chiamate incrociate void fun1() { cout<<”fun1”<<endl ; fun2(); • Ancora non è stata dichiarata! } • Invertire l'ordine di definizione delle funzioni non risolverebbe void fun2() il problema ... { cout<<”fun2”<<endl ; fun1(); } Programmazione - Paolo Valente, 2008/2009
  • 42. Dichiarazione della funzione • Una dichiarazione (senza definizione) o prototipo è costituita dalla sola intestazione di una funzione seguita da ; <dich-funzione> ::= <intestazione-funzione> ; <intestazione-funzione> ::= <nomeTipo> <nomeFunzione> ( <lista-parametri> ) <lista-parametri> ::= void | <dich-parametro> { , <dich-parametro> } <dich-parametro> ::= <nomeTipo> [<identificatore>] Opzionale ! Programmazione - Paolo Valente, 2008/2009
  • 43. Soluzione chiamate incrociate ... void fun2() ; void fun1() { cout<<”fun1”<<endl ; fun2(); } void fun2() { cout<<”fun2”<<endl ; fun1(); } Programmazione - Paolo Valente, 2008/2009
  • 44. Altri esempi di prototipi int fattoriale (int); /* della funzione precedente */ … int fattoriale (int n) { int i, fatt=1; for (i=1; i<=n; i++) fatt = fatt*i; return(fatt); } ___________________________________ int max (int, int, int) ; /* calcola il max di 3 int */ Programmazione - Paolo Valente, 2008/2009
  • 45. Prototipi e definizioni • Il prototipo: – è un puro “avviso ai naviganti” – non produce alcun byte di codice – quindi, se lo si ripete non succede niente di male (basta che non ci siano due dichiarazioni in contraddizione) – può comparire anche dentro un'altra funzione • La definizione, invece: – contiene il vero codice della funzione – non può essere duplicata!! (altrimenti ci sarebbero due codici per la stessa funzione) – il nome dei parametri formali, non necessario in un prototipo, è più importante in una definizione QUINDI: il prototipo di una funzione può comparire più volte, ma la funzione deve essere definita una sola volta. Programmazione - Paolo Valente, 2008/2009
  • 46. I tre elementi fondamentali per comprendere le funzioni • Definizione e dichiarazione della funzione • Uso della funzione (chiamata) • Esecuzione della funzione (record di attivazione) Programmazione - Paolo Valente, 2008/2009
  • 47. Esempio: programma (errato) #include <iostream> using namespace std ; int main() { int a, b; cin>>a>>b ; cout<<quot;Il massimo tra quot;<<a<<quot; e quot;<<b<<quot; e' quot;<<max(a,b)<<endl ; return 0 ; } int max(int a, int b) { if (a > b) return a ; return b ; } Programmazione - Paolo Valente, 2008/2009
  • 48. Esempio: programma (corretto) 1/2 #include <iostream> using namespace std ; int max(int a, int b) { if (a > b) return a ; return b ; } int main() { int a, b; cin>>a>>b ; cout<<quot;Il massimo tra quot;<<a<<quot; e quot;<<b<<quot; e' quot;<<max(a,b)<<endl ; return 0 ; } Programmazione - Paolo Valente, 2008/2009
  • 49. Esempio: programma (corretto) 2/2 #include <iostream> using namespace std ; Tipo dei parametri int max(int, int) ; Ad esempio, scrivere int main() int max(int a, int c) ; { sarebbe stato equivalente int a, b; cin>>a>>b ; cout<<quot;Il massimo tra quot;<<a<<quot; e quot;<<b<<quot; e' quot;<<max(a,b)<<endl ; return 0 ; Parametri attuali } (espressioni) int max(int a, int b) { if (a > b) Parametri formali return a ; (variabili) return b ; } Programmazione - Paolo Valente, 2008/2009
  • 50. Esercizio 1 (Specifica) • Scrivere una funzione che verifichi se un numero naturale fornito dal main() è primo • La funzione deve restituire false se il numero non è primo, true se il numero è primo • E' proprio la funzione che ci serve per completare il programma che abbiamo usato per introdurre l'utilità delle funzioni all'inizio di questa presentazione Programmazione - Paolo Valente, 2008/2009
  • 51. Esercizio 1 (Programma) bool isPrime(int n) { int max_div ; /* 1,2,3 → sì */ if (n>=1 && n<=3) return true; if (n%2==0) return false; /* no perché numeri pari */ max_div = static_cast<int>(sqrt(n)) ; for(int i=3; i<=max_div; i=i+2) if (n%i==0) return false; /* no perché è stato trovato un divisore */ return true; } Programmazione - Paolo Valente, 2008/2009
  • 52. Istruzione vuota ; • E' un semplice • Non fa nulla • Sintatticamente è trattata come una qualsiasi altra istruzione • Esempio: // ciclo che si ferma quando num è primo for(int num = 10001 ; ! isPrime(num) ; num += 2) ; // non fa nulla Programmazione - Paolo Valente, 2008/2009
  • 53. Esercizio 2 (Specifica) • Scrivere una funzione radice che calcoli la radice quadrata (intera) di un valore naturale N. Programmazione - Paolo Valente, 2008/2009
  • 54. Esercizio 2 (Idea e Algoritmo) int radice(int n); < restituisce il massimo intero x tale che x*x ≤ n > • Considera un naturale dopo l’altro a partire da 1 e calcolane il quadrato • Fermati appena tale quadrato supera n • Il risultato corrisponde al valore dell’ultimo numero tale per cui vale la relazione: x*x ≤ n Programmazione - Paolo Valente, 2008/2009
  • 55. Esercizio 2 (Programma) int radice_intera(int n) { int radice; for (int i=1; i <= n; i++) if (i*i>n) radice=i-1; return radice; } Funziona? Programmazione - Paolo Valente, 2008/2009
  • 56. Esercizio 2 (Programma –versione OK) int radice_intera(int n) { int i, radice=1; for (i=1; i*i <= n; i++) ; // istruzione vuota radice=i-1; return radice; } Programmazione - Paolo Valente, 2008/2009
  • 57. Nota sul passaggio dei parametri in C/C++ Programmazione - Paolo Valente, 2008/2009
  • 58. Passaggio dei parametri • Per “passaggio dei parametri” si intende l’associazione fra parametri attuali e parametri formali che avviene al momento della chiamata di una funzione • L'unico meccanismo adottato in C, è il PASSAGGIO PER VALORE • Come vedremo, in C++ disponiamo anche del passaggio per riferimento Programmazione - Paolo Valente, 2008/2009
  • 59. Passaggio dei parametri per valore Le locazioni di memoria corrispondenti ai parametri formali: • Sono allocate al momento della chiamata della funzione • Sono inizializzate con i valori dei corrispondenti parametri attuali trasmessi dalla funzione chiamante • Vivono per tutto il tempo in cui la funzione è in esecuzione • Sono deallocate quando la funzione termina QUINDI • La funzione chiamata riceve copia dei valori dei parametri attuali passati dalla funzione chiamante • Tali copie sono sue copie private che servono solo per inizializzare i parametri formali • Ogni modifica ai parametri formali è strettamente locale alla funzione • I parametri attuali della funzione chiamante non saranno mai modificati! Programmazione - Paolo Valente, 2008/2009
  • 60. Esempio • Prototipo di funzione double CalcDistance (int, int, int, int); • Definizione di funzione double CalcDistance (int px1, int py1, int px2, int py2) { px1 = pow (px1 - px2, 2); py2 = pow (py1 - py2, 2); Il collegamento tra parametri return sqrt(px1 + py2) ; formali e parametri attuali si ha } solo al momento della chiamata. Sebbene px1 e py2 vengano • Chiamata di funzione modificati all’interno della int a= 9, b= 5, c=4, d=12; double dist; funzione, i valori dei cout<<a<<b<<c<<d<<endl; corrispondenti parametri attuali dist = CalcDistance (a, b, c, d); (a, d) rimangono inalterati. Quindi gli stessi valori di a e d cout<<a<<b<<c<<d<<dist<<endl; sono stampati prima e dopo Programmazione - Paolo Valente, 2008/2009
  • 61. Esempio 2 int fattoriale (int n) { int fatt=1; // con variabile ausiliaria i for (int i=1; i<=n; i++) fatt = fatt*i; return fatt; } main() { int risultato, n = 4 ; risultato = fattoriale(n); cout<<“fattoriale(“<<n<<”) = “<<risultato<<endl ; } Stampa fattoriale(4) = 24 Programmazione - Paolo Valente, 2008/2009
  • 62. Esercizio • Provare a realizzare il calcolo del fattoriale mediante una funzione senza utilizzare la precedente variabile ausiliaria Programmazione - Paolo Valente, 2008/2009
  • 63. Esempio 2bis int fattoriale (int n) { if (n == 0) return 1; int fatt = n; // senza variabile ausiliaria i for (n--; n > 0; n--) fatt = fatt*n; return(fatt); Anche se il parametro formale n viene modificato, } la variabile n definita nel main non viene alterata! E’ il suo valore (4) che viene passato alla funzione. main() { int risultato, n = 4 ; Stampa risultato = fattoriale(n); fattoriale(4) = 24 cout<<“fattoriale(“<<n<<”) = “<<risultato<<endl ; } Programmazione - Paolo Valente, 2008/2009
  • 64. Commenti al passaggio per valore • E’ sicuro: le variabili del chiamante e del chiamato sono completamente disaccoppiate • Consente di ragionare per componenti e servizi: la struttura interna dei singoli componenti è irrilevante (la funzione può anche modificare i parametri ricevuti senza che ciò abbia impatto sul chiamante) • LIMITI – impedisce a priori di scrivere funzioni che abbiano come scopo proprio quello di modificare i dati passati dall’ambiente chiamante – come vedremo può essere costoso per dati di grosse dimensioni Programmazione - Paolo Valente, 2008/2009
  • 65. Domanda • Se un parametro formale è dichiarato di tipo const, lo si può poi modificare all'interno della funzione? • Esempio: int fun(const int j) { j++ ; } Programmazione - Paolo Valente, 2008/2009
  • 66. Risposta • Ovviamente no • Il parametro è inizializzato all'atto della chiamata della funzione, e da quel momento non potrà più essere modificato • Quindi: int fun(const int j) { j++ ; // ERRATO !! NON VERRA' COMPILATO } Programmazione - Paolo Valente, 2008/2009
  • 67. Nota 1/2 • Abbiamo visto la modifica di un parametro formale variabile all'intero di una funzione solo per capire che la cosa si può fare, e che tale parametro è perfettamente equivalente ad una variabile locale • Tuttavia, è fondamentale avere presente che – In generale è una cattiva abitudine modificare i parametri formali per utilizzarli come variabili ausiliarie o Poca leggibilità o Rischioso nel caso di parametri passati per riferimento (che vedremo nelle prossime lezioni) Programmazione - Paolo Valente, 2008/2009
  • 68. Nota 2/2 • L'unico caso in cui è necessario ed appropriato modificare i parametri formali è quando tali parametri sono intesi come parametri di uscita, ossia parametri in cui devono essere memorizzati valori che saranno poi utilizzati da chi ha invocato la funzione • Questo non può però accadere nel caso di passaggio per valore, perché i parametri formali sono oggetti locali alla funzione, e saranno quindi eliminati alla terminazione della funzione stessa • Vedremo invece più avanti come implementare i parametri di uscita mediante il passaggio per riferimento Programmazione - Paolo Valente, 2008/2009
  • 69. Nota conclusiva sui vantaggi delle funzioni • Testo del programma suddiviso in unità significative • Testo di ogni unità più breve – minore probabilità di errori – migliore verificabilità • Riutilizzo di codice • Migliore leggibilità • Supporto allo sviluppo top-down del software – Si può progettare prima quello che c'è da fare in generale, e poi si può realizzare ogni singola parte Programmazione - Paolo Valente, 2008/2009