prof. Nunzio Brugaletta
C++: programmazione e oggetti

EnneBi - Programmazione
Avanti - Indietro - Inizio

Funzioni e parametri in C++: un esempio pratico

Nel linguaggio C++ tutti i parametri sono passati alle funzioni per valore, e ciò allo scopo di isolare quanto più possibile la funzione e renderla riutilizzabile. Per passare alla funzione un parametro per riferimento è necessario utilizzare il simbolo & attaccato alla fine della dichiarazione di tipo della variabile o all’inizio del nome della variabile stessa.

La funzione, nella sua definizione, preparerà variabili locali per ricevere i parametri passati dal chiamante. Nel caso di passaggio per indirizzo, ogni variazione effettuata dalla funzione sul contenuto della variabile locale si ripercuoterà sulla variabile corrispondente del chiamante.

I parametri passati dal chiamante sono comunemente chiamati argomenti o parametri reali, mentre quelli presenti nella definizione della funzione sono chiamati parametri formali.

A questo punto viene proposta la codifica del programma sulle elaborazioni statistiche di temperature.

#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
using namespace std;

namespace temperature{	/*1*/
  const int numero=12;	/*2*/

  vector<float> rileva();	/*3*/
  void elab(vector<float>, float&, float&, float&);	/*3*/
  void statistiche(float, float, float);	/*3*/

  void calcMedMnMx(vector<float>, float&, float&, float&);	/*4*/
  float calcEscursione(float mn,float mx){return mx-mn;};	/*4*/
  float calcScostMedio(vector<float>, float);	/*4*/
}

int main()
{
  vector<float> temp;	/*5*/
  float tempMedia,escursione,scostamento;	/*5*/

  cout << "Data una serie di rilevazioni di temperature" << endl
       << "calcola temperatura media, escursione termica, "
       << "scostamento medio" << endl;

  temp = temperature::rileva();	/*6*/
  temperature::elab(temp,tempMedia,escursione,scostamento);	/*6*/
  temperature::statistiche(tempMedia,escursione,scostamento);	/*6*/

  return 0;
}

// Rilevazione temperature

vector<float> temperature::rileva()	/*7*/
{	
  vector<float> t;
  float tempinp;
  int i;

  cout << "\nRilevazione di " << temperature::numero << " temperature" << endl;
  for(i=0;i<temperature::numero;i++){
    cout << "Introdurre rilevazione " << i+1 << " ";
    cin >> tempinp;
    t.push_back(tempinp);
  };

  return t;
}

// Elaborazioni sulle temperature rilevate

void temperature::elab(vector<float> t,float& tm,float& et,float &sm)
{
  float tMin,tMax;

  temperature::calcMedMnMx(t,tm,tMin,tMax);
  et = temperature::calcEscursione(tMin,tMax);	/*8*/
  sm = temperature::calcScostMedio(t,tm);	/*8*/
}

// Output statistiche richieste

void temperature::statistiche(float tm,float et,float sm)
{
  cout << "\nTemperatura media :" << tm << endl;
  cout << "Escursione termica :"  << et << endl;
  cout << "Scostamento medio :"   << sm << endl;
}

// Calcolo temperature media, minima, massima

void temperature::calcMedMnMx(vector<float> t2,float& m,float& mn,float& mx)
{
  float sommatemp=0.0;
  int i;

  min=max=t2.at(0);
  sommatemp += t2.at(0);
  for(i=1;i<temperature::numero;i++){
    sommatemp += t2.at(i);
    mn = min(mn,t2.at(i));	/*9*/
    mx = max(mx,t2.at(i));	/*9*/
  }
  m = sommatemp/temperature::numero;
}

// Calcolo scostamento medio

float temperature::calcScostMedio(vector<float> t2,float m)
{
  float sommaScost=0.0,scost;
  int i;

  for(i=0;i<temperature::numero;i++)
    sommaScost += fabs(t2.at(i)-m);	/*10*/
  
  return sommaScost/temperature::numero;
}

Nella 1 viene definito uno spazio per i nomi che conterrà tutte le dichiarazioni che verranno utilizzate nel programma. È questa una buona abitudine che permette di fare riferimento, nel corso del programma, a quanto contenuto in temperature, senza preoccuparsi se in altre librerie ci sono funzioni che hanno lo stesso nome.

Nella 2 viene definita una costante per la quantità di rilevazioni di temperature effettuate, in modo da utilizzarla tutte le volte che sarà necessario riferirsi a tale dato. Se si vuole modificare la quantità, basta modificare il valore assegnato e ricompilare il programma.

Nelle 3 sono riportati i prototipi delle funzioni principali in cui è stato suddiviso il programma. La rileva si occupa di effettuare l'input del vettore delle temperature. Il vettore, essendo per la funzione un output, è tornato alla funzione chiamante. La funzione elab partendo dal vettore delle temperature, che per essa è un input (parametro passato per valore), fornisce temperatura media, escursione termica e scostamento medio che, dal suo punto di vista, sono output e, di conseguenza, sono parametri passati per riferimento. La funzione statistiche si occupa della visualizzazione dei risultati. I tre dati calcolati sono passati per valore: la funzione deve solo conoscerli, non effettua su di essi alcuna elaborazione.

Le 4 riportano i prototipi delle funzioni che si occupano delle tre elaborazioni richieste. La prima funzione dall'input del vettore fornisce in output temperatura media, minima e massima. La seconda dalla temperatura minima e massima calcola l'escursione termica. La terza dall'input del vettore e dalla temperatura media calcola lo scostamento medio.

La funzione calcEscursione che si occupa semplicemente del calcolo del risultato di una differenza, è implementata direttamente nel prototipo. Sono quelle che vengono chiamate funzioni inline. Questa è una tecnica che, normalmente, si usa quando si tratta, come in questo caso, di funzioni che comprendono poche righe di codice. La differenza con la definizione delle altre funzioni consiste nel modo in cui vengono trattate dal compilatore:

In definitiva le funzioni inline sono eseguite in modo più rapido ma occupano più spazio essendo ogni volta, per ogni chiamata, presente il codice della funzione. Questa è sostanzialmente la ragione perché è una tecnica che viene utilizzata per funzioni contenenti poche righe di codice.

Nelle 5 sono dichiarate le variabili che necessitano al programma che, per come è stato scomposto, si riducono alle variabili di input e di output del programma stesso. Qualsiasi altra variabile sarà definita nella funzione che ne avrà bisogno.

Nelle 6 vengono richiamate in sequenza le tre funzioni principali in cui è stato suddiviso il programma. È usato l'operatore di visibilità per dichiarare lo spazio dei nomi in cui sono dichiarate le funzioni richiamate; se non fosse stato specificato, il compilatore avrebbe generato errore. Nella chiamata alle funzioni sono passati i parametri reali: le variabili per come sono conosciute dalla main.

La definizione della funzione in 7, richiede le temperature rilevate e le conserva in un vettore che viene ritornato al chiamante. Si fa notare che anche se un oggetto di tipo vector contiene più elementi è un oggetto e può essere utilizzato come valore di ritorno che deve essere assegnato, da parte del chiamante, ad un oggetto della stessa classe (un oggetto di tipo vector<float>).

Le chiamate presenti nelle 8 riguardano funzioni che ritornano un valore diverso da void, nel caso specifico di tipo float. È necessario assegnare ad una variabile di tipo float la chiamata alla funzione: infatti l'esecuzione della chiamata provoca, nei due casi, il calcolo di un valore di tipo float così come dichiarato nelle 4.

Nelle 9 sono usate due funzioni contenute nella libreria algorithm inclusa nel programma. Si tratta di due funzioni che restituiscono, rispettivamente, il valore minimo e il valore massimo dei due parametri. Nel programma vengono utilizzate per controllare se le variabili, che conservano tali valori, necessitano di aggiornamento in relazione al confronto con l'elemento del vettore.

Nella 10 è utilizzata una funzione, contenuta nella libreria cmath, che calcola il valore assoluto del parametro. La libreria cmath contiene altre funzioni (tutte restituiscono un valore in virgola mobile) che possono essere utili nelle applicazioni matematiche:

La libreria contiene anche funzioni per calcoli trigonometrici, logaritmici.



Avanti - Indietro - Inizio

http://ennebi.solira.org
ennebi@solira.org