Le frazioni sono uno degli argomenti più gettonati per fare esperienza col codice e il c++. Ci sono diversi modi di contemplare ed approcciare questi strumenti matematici. Vediamo un esempio semplice, adatto a chi non conosce ancora la programmazione ad oggetti ma ha già una discreta esperienza col codice.
Le operazioni con le frazioni si prestano molto all’uso delle funzioni ecco perché dichiariamo subito i prototipi che ci serviranno.
void leggifrazione(int &, int &);
void stampafrazione(int, int);
float MCD(int, int);
float mcm(int, int);
float somma(int, int, int, int);
void sommafrazione(int, int, int, int, int &, int &);
Come potrà notare il lettore, i prototipi non richiedono il nome di una variabile, il classico int n, ma solo il tipo del parametro stesso, in questo caso int. L’idea alla base del nostro esercizio è che l’utente può inserire da tastiera numeratore e denominatore ed effettuare le classiche ed immediate operazioni di somma, massimo comun divisore, minimo comune multiplo. La somma viene restituita in due modalità: o la frazione stampata numeratore/denominatore, o il valore calcolato. Forse anomalo per l’alunno inesperto sono le funzioni void di lettura e stampa, in realtà molto utili se nel programma main ci fosse la necessità di leggere o stampare a video molte frazioni. Tutte le funzioni prendono parametri “per copia”, ovvero dal programma main o altra funzione vengono passati dei valori per eseguire i vari calcoli ma come una copia che non altera il contenuto della variabile che viene “passata” ovvero copiata. Tutte tranne un paio! Il leggifrazione infatti prende due parametri che saranno il numeratore ed il denominatore della frazione ma i parametri presentano la &, ovvero il passaggio di parametro per riferimento. Questo implica che il valore passato alla funzione non è semplicemente copiato, ma qualunque attività si effettui su quel parametro nella funzione, si riversa nella variabile del programma main che lo ha passato. Questo è fondamentale per superare un limite del C++ in modalità classica, non ad oggetti. Le funzioni infatti tornano un solo valore ma la frazione è composta da due valori, quindi occorre questo stratagemma per poter valorizzare la frazione con una funzione, in questo caso semplice, ma che è molto comoda. La seconda funzione con parametri passati per riferimento è la sommafrazione. Questa prende in input i parametri delle due frazioni da sommare con i rispettivi numeratori e denominatori e restituisce il risultato in due parametri con la & per restituire al programma main una terza frazione risultato della somma. Anche qui: sommafrazione dovrebbe tornare due valori per il numeratore e denominatore ma le funzioni tornano solo un valore, quindi occorre questo trucco per superare i problemi di comunicazione e ritorno di più valori tra main e funzione di supporto.
A questo punto addentriamoci nel programma main. La dichiarazione delle variabili è semplice ed intuitiva per il nostro scopo: inserire due frazioni da tastiera con numeratore e denominatore, una terza coppia per immagazzinare e visualizzare la frazione risultato della somma e un semplice variabile float per il valore calcolato della frazione risultato della somma.
int n1,d1; //prima frazione
int n2,d2; //seconda frazione
int n3,d3; //terza frazione
float sf = 0;
A questo punto effettuiamo la lettura dei valori da console/tastiera in input. Utilizziamo le funzioni leggifrazioni che passano i valori numeratore e denominatore che saranno sovrascritti con i valori inseriti da tastiera e saranno quindi spendibili anche nel corpo del programma main
. Le funzioni di lettura sono molto semplici ed intuitive in realtà dal punto di vista del codice ma è buona norma che lo studente si abitui a creare funzioni su misura per leggere dati che possano avere una numerosità elevata in contesti reali.
leggifrazione(n1,d1);
leggifrazione(n2,d2);
A questo punto possiamo occuparci delle funzioni MCD e mcm che in realtà non hanno particolari criticità se non quelle di tradurre le formule matematiche note. Il massimo comun divisore il realtà è un divisore comune dei due numeri posti in ingresso alla funzione (i denominatori in realtà). Quindi bisogna semplicemente scorrere con un indice incrementale tutti i numeri e controllare se dividono entrambi i due parametri. Tra tutti i divisori, va trovato il maggiore. La ricerca si ferma quando si arriva a metà del più piccolo. Come ragionare a voce alta? Si comincia da 1: 1 divide i due parametri in ingresso? Si, allora è il nuovo divisore comune. E’ il massimo? No, non è detto vado avanti. Due divide entrambi i numeri? Se si, è il nuovo divisore comune temporaneamente più alto, altrimenti vado oltre. Passo a 3 e così via. I due casi tendono ad individuare qual è il più piccolo tra i due numeri sondati per interrompere il ciclo a n/2 o m/2. Il terzo caso si presenta se n e d sono uguali, caso in cui il MCD è il numero stesso.
float MCD(int n, int d)
{
float mcd = 0;
if (n < d)
{
for (int i=1; i <n/2; i++)
{
if (n % i == 0 && d % i == 0)
mcd = i;
}
}
if (d < n)
{
for (int i=1; i <d/2; i++)
{
if (n % i == 0 && d % i == 0)
mcd = i;
}
}
if (n == d)
mcd = n;
return mcd;
}
mcm e somma non meritano particolari interessi perché mere applicazioni delle regole matematiche. Unica nota interessante dello mcm è che viene richiamata una funzione dentro un’altra funzione, cosa anomala magari per lo studente che sino ad oggi le funzioni le richiamava solo dal main senza però accorgersi che il main stesso è una funzione! Analogo discorso per la somma che richiama lo mcm ed effettua le operazioni matematiche da regola.
Il codice completo del main.cpp
#include <iostream>
using namespace std;
void leggifrazione(int &, int &);
void stampafrazione(int, int);
float MCD(int, int);
float mcm(int, int);
float somma(int, int, int, int);
void sommafrazione(int, int, int, int, int &, int &);
int main()
{
int n1,d1; //prima frazione
int n2,d2; //seconda frazione
int n3,d3; //terza frazione
float sf = 0;
leggifrazione(n1,d1);
leggifrazione(n2,d2);
sf = somma(n1,d1,n2,d2);
sommafrazione(n1,d1,n2,d2,n3,d3);
cout << "MCD= " << MCD(d1,d2) << endl;
cout << "mcm= " << mcm(d1,d2)<< endl;
cout << "somma= " << sf << endl;
cout << "somma= ";
stampafrazione(n3,d3);
return 0;
}
void leggifrazione(int &n, int &d)
{
cout << "Inserisci il numeratore" << endl;
cin >> n;
cout << "Inserisci il denominatore" << endl;
cin >> d;
}
void stampafrazione(int n, int d)
{
cout << n << "/" << d <<endl;
}
float MCD(int n, int d)
{
float mcd = 0;
if (n < d)
{
for (int i=1; i <n/2; i++)
{
if (n % i == 0 && d % i == 0)
mcd = i;
}
}
if (d < n)
{
for (int i=1; i <d/2; i++)
{
if (n % i == 0 && d % i == 0)
mcd = i;
}
}
if (n == d)
mcd = n;
return mcd;
}
float mcm(int d1, int d2 )
{
float mcd = MCD(d1,d2);
float mcm = d1*d2/mcd;
return mcm;
}
float somma(int n1, int d1, int n2, int d2)
{
float somma = 0;
float minconmul = mcm(d1, d2);
float num1 = (minconmul / d1) * n1;
float num2 = (minconmul / d2) * n2;
somma = (num1 + num2) / minconmul;
return somma;
}
void sommafrazione(int n1, int d1, int n2, int d2, int &nr, int &dr)
{
float somma = 0;
float minconmul = mcm(d1, d2);
float num1 = (minconmul / d1) * n1;
float num2 = (minconmul / d2) * n2;
nr = (num1 + num2) ;
dr = minconmul;
return;
}
Ultima modifica 5 Aprile 2023