C funzioni à argomenti
Gli argomenti di una funzione (o procedura) possono essere:
di input, cioè i dati passati alla funzione perché essa possa effettuare calcoli
Passaggio per VALORE
di output, cioè le variabili non inizializzate passate alla funzione che assumeranno un valore al termine della funzione (procedura)
di input-output, cioè le variabili passate alla funzione che hanno un loro valore prima della chiamata della procedura e che al termine della procedura possono assumere un valore diverso
Passaggio per RIFERIMENTO
C funzioni à argomenti
Problema: Calcolare la somma di due frazioni n1/d1, n2/d2 e ridurla ai minimi termini.
Primo raffinamento:
leggi(n1,d1,n2,d2)
calcola il numeratore, num, ed il denominatore, den, della somma riduci num e den ai minimi termini
stampa(num e den)
I quattro numeri in input non possono essere quattro interi qualsiasi perché un denominatore non può mai essere zero.
Quindi precondizioni: d1≠0 e d2≠0
Per ridurre num e den ai minimi termini dobbiamo prima trovare il massimo comun divisore k, e successivamente effettuare le operazioni num¬num/k, den¬den/k.
C funzioni à argomenti
Nella procedura leggi i quattro parametri della procedura sono tutti di output.
Nella procedura calcolasomma gli stessi sono invece parametri di input mentre num e den sono parametri di output.
Nella procedura riduci num e den sono parametri di input-output.
Nella procedura stampa sono parametri di input.
C funzioni à argomenti
Definiamo una funzione per l’algoritmo (di Euclide) che calcola il MCD di due interi a e b:
Si tratta di una vera funzione perché gli argomenti sono usati solo per il calcolo del MCD
a e b sono argomenti di input
function mcd(a,b):
r ß modulo(a,b) while (r > 0):
a ß b b ß r
r ß modulo(a,b) return b:
pseudocodice
int mcd (int a, int b) { int r;
r = a % b;
while (r>0) { a = b;
b = r;
r = a % b;
} return b;
}
codice C
C funzioni à argomenti
Definiamo una funzione per la riduzione di una frazione ai minimi termini, con argomenti numeratore e denominatore:
Si tratta di una procedura perché non c’è valore di ritorno; l’effetto del calcolo è modificare gli argomenti num e den
num e den sono argomenti di input-output
function
riduci(?num,?den):
k ß mcd(num, den) num ß num / k
den ß den / k return:
pseudocodice
C funzioni à argomenti
Nella funzione mcd le variabili a,b si riferiscono al loro valore
(right value), mentre nella funzione riduci le variabili num e
den al loro indirizzo (left value).
C funzioni à argomenti
Interfacciamento: l’insieme di operazioni che occorre fare per rendere possibili le due fasi dell’invocazione di funzione
1. chiamata della funzione: passaggio di
parametri dalla funzione chiamante alla funzione chiamata (come suoi argomenti)
controllo dalla funzione chiamante alla funzione chiamata 2. ritorno della funzione: passaggio di
valore di ritorno della funzione chiamata alla funzione chiamante
controllo dalla funzione chiamata (al suo termine) alla funzione chiamante
void foo(...) { } ...
main { ...foo() } ..
invocazione
ritorno
C funzioni à argomenti
Record di Attivazione
La memoria effettivamente usata dal programma a runtime è organizzata come una pila o stack.
Inizialmente una certa area di memoria è riservata al main.
Una chiamata ad una function corrisponde alla allocazione di una opportuna area di memoria detta record di attivazione della function.
Nel record di attivazione è assegnato uno spazio opportuno, dipendente dal
tipo, ad ognuno dei parametri della function e ad ogni variabile locale
(cioè definita all’interno della function).
C funzioni à argomenti
Il C usa una struttura di memoria detta stack per gestire
l’interfacciamento tra funzione chiamante e funzione chiamata Lo stack è formato da una pila di aree di memoria detti record di
attivazione, uno per ogni chiamata di funzione, contenente:
le variabili automatiche della funzione chiamata;
la lista degli argomenti della funzione in cui sono copiati i valori trasmessi dalla funzione chiamante;
l'indirizzo di rientro, cioè il riferimento all’istruzione della funzione chiamante che deve essere eseguita una volta completata la funzione chiamata
(trasferendovi l'eventuale valore di ritorno)
stack int mcd(...) {
} ...
mcd
void foo(...) { } ...
foo
main {
main
} ...
Record di attivazione
invocazione
C funzioni à argomenti
Quando il controllo deve tornare dalla funzione chiamata alla
chiamante, il programma fa riferimento all'ultimo record dello stack per:
conoscere l'indirizzo di rientro nella funzione chiamante
eseguita tale operazione, rimuove lo stesso record dallo stack (cancellando di conseguenza anche le variabili automatiche)
int mcd(...) { } ...
mcd
stack
main
Record diattivazionevoid foo(...) { } ...
foo
main { } ...
ritorno
C funzioni à argomenti
passaggio dei parametri per valore: come argomento viene assegnato una copia del valore del parametro
• La funzione può anche modificarne il valore senza che nessuna delle variabili del processo chiamante ne risulti modificata
• Le modifiche hanno effetto solo nell’ambito dell’esecuzione della funzione
void foo(...) { ...k = mcd(a1,a2) } ...
funzione chiamante
int mcd(int a, int b){
int r;
} ...
a 28
b 12
Indirizzo di rientro in foo
r
Record di attivazione funzione chiamata
... automatiche
Indirizzo di rientro in main
...k
automatiche
a2
a1 28
12
copia
argomenti
main {
C funzioni à argomenti
passaggio dei parametri per riferimento (per indirizzo): come parametro della funzione viene passato l’indirizzo di una variabile
• L’argomento deve essere di tipo puntatore al tipo del dato su cui si opera
• L’argomento (il suo nome) si comporta come un sinonimo (alias) del corrispondente parametro passato
Record di attivazione a
b
Indirizzo di rientro in foo
...r automatiche
Indirizzo di rientro in main
...k
automatiche
a2
a1 28
12
argomenti
void foo(...) {
...k = mcd(&a1,&a2) } ...
funzione chiamante
int mcd(int *a, int *b){
int r;
} ...
funzione chiamata
main {
C funzioni à argomenti
Suggerimento:
• Tutto i dati che servono ad una procedura per poter effettuare i suoi calcoli (parametri di input), devono essere passati per valore.
• Tutte le variabili definite nel processo chiamante che la procedura
deve modificare o inizializzare (parametri di input-output, parametri
di output), devono essere passati per riferimento.
C funzioni à argomenti
Regola
E’ errato dichiarare due parametri dello stesso tipo nella forma
double x, y anziché nella forma double x, double y. Si commette un errore di sintassi. Ogni parametro deve essere specificato
con il tipo di dato a cui appartiene.
C funzioni à argomenti
riduci(int *n, int *d)
Viene segnalato un errore in corrispondenza della chiamata:
riduci(&num+1,&den);
Infatti num+1 è un’espressione cui dovrebbe corrispondere nella intestazione della function un parametro per passaggio di valore mentre il primo argomento di riduci è un riferimento.
Una soluzione può essere:
num++;
riduci(&num,&den);
C funzioni à argomenti
E’ sempre possibile trasformare una funzione in una procedura (e viceversa):
• aggiungendo un parametro t di output dello stesso tipo del valore di ritorno della funzione
• il corpo della procedura si ottiene dal corpo della funzione,
sostituendo ogni enunciato del tipo return espr; con l’enunciato t=espr;
Esempio:
int calcola(int p,… ,float q,int *r,…,float *s)
void calcola(int p,… ,float q,int *r,…,float *s,int *t)
Suggerimento:
Scrivere una funzione che ritorna un valore solo se tutti suoi parametri
devono essere passati per valore. In tutti gli altri casi scrivere una
procedura.
C funzioni à esercizio
Problema
Somma di due frazioni con riduzione ai minimi termini
1. Analisi del problema: una soluzione esiste e viene dall'aritmetica:
Input: n1, d1 numeratore e denominatore della 1a frazione n2, d2 numeratore e denominatore della 2a frazione
Output: n, d numeratore e denominatore della frazione somma delle due e ridotta ai minimi termini
La somma di due frazioni è data dalla formula:
Dopodiché la somma dovrà essere ridotta ai minimi termini usando il massimo comun divisore (M)
n1 n2
d1 + d2 = n1 ´ d2 + n2 ´ d1 d1 ´ d2
n'
= d'
n
d =n' / M d' / M
C funzioni à esercizio
2. Individuare un algoritmo (G): individuare una successione finita di azioni che, in prima approssimazione, risolve il problema
leggi n1,d1,n2,d2
calcola il numeratore, num, ed il denominatore, den, della somma riduci num e den ai minimi termini
stampa num e den leggi(n1,d1,n2,d2)
calcola_somma(n1,d1,n2,d2,n,d) riduci(n,d)
stampa(n, d)
C funzioni à esercizio
leggi: precondizioni: le quattro variabili devono essere di tipo intero;
postcondizioni: le quattro variabili hanno ricevuto i valori che l’utente ha inserito e d1 e d2 devono essere dei numeri diversi da zero.
calcolasomma: precondizione: n1,d1,n2,d2 devono avere i valori inseriti dall’utente;
postcondizione: num e den devono rappresentare il numeratore ed il denominatore della somma.
riduci: precondizione: num e den rappresentano numeratore e denominatore di una frazione;
postcondizione: num e den rappresentano il numeratore ed il denominatore della stessa frazione, ma ridotta ai minimi termini.
stampa: precondizione: num e den sono i valori della frazione ridotta ai minimi termini;
postcondizione: che questi siano stampati a video.
Per le prime tre procedure dopo la loro chiamata lo stato del sistema cambia mentre per l’ultima l’insieme delle variabili del sistema non subisce alcun cambiamento.
C funzioni à esercizio
3. Verifica e raffinamento: ogni macroazione va raffinata
• La consideriamo come un sottoproblema di quello generale e per ogni sottoproblema cerchiamo un algoritmo (punto 2.)
leggi(n1,d1,n2,d2)
calcola_somma(n1,d1,n2,d2,n,d) riduci(n,d)
stampa(n,d)
function calcola_somma(na,da,nb,db, n,d)n ß na ´ db + nb ´ da
d ß da ´ db
Pre: argomenti interi, da¹0, db¹0
Post: n,d interi e d¹0
function riduci(?n,?d):
M ß mcd(n,d) n ß n / M
d ß d / M return:
Pre: argomenti interi, d¹0
Post: n,d interi e d¹0 Post: n,d interi e d¹0
C funzioni à esercizio
3. Verifica e raffinamento: ogni macroazione va raffinata
• La consideriamo come un sottoproblema di quello generale e per ogni sottoproblema cerchiamo un algoritmo (punto 2.)
function calcola_somma(na,da,nb,db, n,d)n ß na ´ db + nb ´ da
d ß da ´ db
Pre: argomenti interi, da¹0, db¹0
Post: n,d interi e d¹0
function riduci(?n,?d):
M ß mcd(n,d) n ß n / M
d ß d / M return:
Pre: argomenti interi, d¹0
Post: n,d interi e d¹0 Post: n,d interi e d¹0
function mcd(a,b):
r ß modulo(a,b) while (r > 0):
a ß b b ß r
r ß modulo(a,b) return b
:
Pre: argomenti interi, a,b
¹
0Post: b intero >0
C funzioni à esercizio
Non è detto che, scritto il codice, non si riconsideri un’altra soluzione o una variante della prima soluzione (+efficiente)
1. (Ri)analisi del problema:
La somma delle due frazioni può essere ridotta usando il minimo comune multiplo (m) dei denominatori:
Detto M il massimo comun divisore dei denominatori, si ha:
Dopodiché la somma dovrà essere ridotta ai minimi termini usando il massimo comun divisore di (M) (come prima)
n1 n2
d1 + d2 = n1 ´ d2/m + n2 ´ d1/m m
n
d = n'/M d'/M n' d'
=
= d1 ´ d2
m M
C funzioni à esercizio
3. Verifica e raffinamento: grazie al metodo dei raffinamenti successivi (e dell’astrazione procedurale) possiamo
• modificare l’algoritmo del singolo task della somma di frazioni
• … lasciando inalterate le altre parti (e il codice) dell’algoritmo
function
calcola_somma(na,da,nb,db,?n,?d ):m ß mcm(da,db)
n ß na ´ m / da + nb ´ m / db d ß m
return:
Pre: argomenti interi, da¹0, db¹0
Post: n,d interi e d¹0
leggi(n1,d1,n2,d2)
calcola_somma(n1,d1,n2,d2, riduci(n,d)n,d)
stampa(n,d) function
calcola_somma(…):
function riduci(?n,?d):
function mcm(m1,m2):
m ß mcd(m1,m2) return (m1 ´ m2 / m):
Pre: argomenti interi
Post: valore intero
function mcd(a,b):
Algoritmo
C funzioni à osservazioni
l’astrazione procedurale consente di evitare inutili duplicazioni di codice (semplicità e leggibilità del codice)
• Codificando l’intero programma senza far uso di funzioni si incorre spesso in duplicazioni
• L’eccesso di chiamate funzionali penalizza le prestazioni (efficienza)
leggi(n1,d1,n2,d2)
... codice per mcd di d1 e d2 ...
m ß ... mcd di d1 e d2 ...
n ß n1 ´ m/d1 +n2 ´ d ßm/d2m
... codice per mcd di n e d M ß...... mcd di n e d ...
n ß n / M d ß d / M stampa(n,d)
function riduci(?n,?d):
M ß mcd(n,d) n ß n / M
d ß d / M return:
function mcm(m1,m2):
m ß mcd(m1,m2) return (m1 ´ m2 / m):
function mcd(a,b):
r ß modulo(a,b) while (r > 0):
a ß b b ß r r ß
modulo(a,b) return b:
C funzioni à osservazioni
l’astrazione procedurale consente di separare il programma in moduli indipendenti (modularità) fornendo la possibilità
• di estensione/modifica di ogni modulo senza condizionare gli altri moduli del programma (estendibilità del codice)
l’astrazione procedurale consente di separare il programma in
moduli indipendenti (modularità) fornendo la possibilità
C funzioni à esercizio
Problema
Assegnata una quantità di centesimi di euro, suddividerla nel numero minimo di monete da 50, 20, 10, 5, 1
1. Analisi del problema:
Chiamiamo X la quantità in centesimi da convertire (input utente)
•
Consideriamo k=5 monete di valore Mi centesimi:M1=50, M2=20, M3=10, M4=5, M5=1
• Calcolare il numero massimo npezzi1 di monete da M1 centesimi in cui possiamo suddividere la quantità X, e diciamo resto il rimanente numero di centesimi. Evidentemente si ha:
npezzi1 = X / M1, resto = X % M1
• per calcolare il numero di pezzi di valore M2 successivo (più basso) in cui possiamo suddividere quanto resta, assegnamo resto a X e calcoliamo:
npezzi2 = X / M2, resto = X % M2
• e così via ... finché resto è nullo npezzii
C funzioni à esercizio
2. Individuare un algoritmo (G), ossia una successione finita di azioni che, in prima approssimazione, risolve il problema
Costruiamo una procedura che accetti in ingresso i centesimi e il valore della moneta e ci restituisca in uscita sia il numero di pezzi di tale tipo di moneta che il numero di centesimi rimasti (dato in input 74 centesimi e 20 come valore della moneta, ci fornisca in uscita 3 ed il numero di centesimi rimasti 14).
Parametri?
Mostra IstruzioniCalcola quante monete servono da 50 cent Calcola quante monete servono da 20 cent
………
Stampa i risultati
C++ funzioni à esercizio
4. implementazione scriviamo il programma principale e i prototipi delle funzioni
/*Assegnati i centesimi iniziali, determina il minimo numero di monete di taglio maggiore da restituire in cambio */
#include <iostream>
#include <cstdlib>
using namespace std;
// DICHIARAZIONI DI FUNCTION
void CalcolaPezzi (int, int &, int &);
void StampaDati (int,int, int, int, int, int);
// MAIN
int main () {
int Centesimi,Pezzi50, Pezzi20, Pezzi10, Pezzi5, Pezzi2, Pezzi1;
cout << "Inserisci i centesimi =";
cin >> Centesimi;
CalcolaPezzi (50,Centesimi,Pezzi50);
CalcolaPezzi (20,Centesimi,Pezzi20);
CalcolaPezzi (10,Centesimi,Pezzi10);
CalcolaPezzi (5,Centesimi,Pezzi5);
CalcolaPezzi(2,Centesimi,Pezzi2);
Pezzi1=Centesimi;
StampaDati (Pezzi50, Pezzi20, Pezzi10, Pezzi5, Pezzi2, Pezzi1);
system(“pause”);
}
C++ funzioni à esercizio
4. Implementazione: scriviamo il codice per il corpo delle funzioni di cui abbiamo già il prototipo
void CalcolaPezzi( int Tpezzo, int &Cent, int &Npezzi) {
/* prec:Cent è la quantità di centesimi che deve essere cambiata in monete aventi valore Tpezzo.
postc: Cent è la quantità di centesimi dopo il cambio, NPezzi è il numero di monete di valore Tpezzo date in cambio */
}
void StampaDati (int Pezzi50, int Pezzi20, int Pezzi10, int Pezzi5, int Pezzi2, int Pezzi1)
{
/* prec: il numero dei vari tipi di moneta dato in cambio postc: stampa dei dati */
}
C funzioni à esercizio
Osservazioni:
Calcolapezzi potrebbe essere una funzione ma la presenza di centesimi che è un parametro di input-output impone di scrivere una procedura.
Abbiamo visto un altro uso molto comune dei sottoprogrammi. Codificando direttamente
l’algoritmo iniziale avremmo dovuto scrivere più volte del codice sostanzialmente simile.
L’utilizzo della procedura CalcolaPezzi ce lo ha evitato.
Si sarebbero potuto anche fondere in una unica procedura CalcolaPezzi e Stampa, la quale, dopo aver calcolato Npezzi, provvedesse anche a stamparlo. Tuttavia così come è scritta
CalcolaPezzi risulta più facilmente riutilizzabile in un altro programma.
Non abbiamo ancora scritto il corpo delle due function. Ma questo programma incompleto può essere compilato. Inoltre introducendo nel corpo delle function un opportuno messaggio di stampa si può verificare se il flusso del programma è quello voluto. Ad esempio si potrebbe inserire in stampa:
cout<<”sono in stampa”
ed in CalcolaPezzi:
cout<<Tpezzo
C funzioni à esercizio
4. Implementazione: scriviamo il codice per il corpo delle funzioni di cui abbiamo già il prototipo
void CalcolaPezzi( int Tpezzo, int &Cent, int &Npezzi) // Calcola il numero di pezzi
{
Npezzi = Cent / Tpezzo;
Cent = Cent % Tpezzo;
}
void StampaDati (int Pezzi50, int Pezzi20, int Pezzi10, int Pezzi5, int Pezzi2, int Pezzi1)
// Stampa i dati {
cout << "Pezzi da 50=" << Pezzi50 <<endl;
cout << "Pezzi da 20=" << Pezzi20 <<endl;
cout << "Pezzi da 10=" << Pezzi10 <<endl;
cout << "Pezzi da 5 =" << Pezzi5 <<endl;
cout << "Pezzi da 2 =" << Pezzi2 <<endl;
cout << "Pezzi da 1 =" << Pezzi1 <<endl;
}
C funzioni à argomenti array
Se gli argomenti di una funzione sono nomi di array il passaggio di parametri avviene sempre per riferimento
Non occorre anteporre l'operatore & nella dichiarazione degli argomenti
Nella definizione di funzione la variabile (identificatore) dell'array è preceduta dal tipo e seguita dalla coppia di parentesi quadre
Esempio:
void sommavet(const int A[], const int B[], int k, int C[]) { for (int i=0; i < k; i++)
C[i] = A[i] + B[i];
}
non serve specificare la dimensione perché é già stata dichiarata nel programma chiamante
se l'array é multidimensionale l'unico indice che si può omettere é quello a sinistra
Lo specificatore const serve a indicare che il parametro è solo in lettura (ogni tentativo di modica nel corpo della funzione è un errore del compilatore)
C funzioni à argomenti array
Nella dichiarazione di funzione (o prototipo) ogni argomento è dichiarato solo con il tipo affiancato dalle parentesi quadre
Esempio:
void sommavet(const int[], const int[], int, int[]);
Per trasmettere un intero array a una funzione bisogna inserire nella chiamata il nome dell'array (senza parentesi quadre):
Esempio:
int vet1[100], vet2[100], vet3[100]
sommavet(vet1, vet2, 100, vet3)
Nel corpo della funzione tutte le modifiche fatte ai singoli elementi
dell'array vengono riprodotte sull'array del programma chiamante
C funzioni à argomenti array
Nel caso di passaggio di parametri come singoli elementi di un array non ci sono eccezioni alla regola generale
Esempio:
Driver di una function
Dato un array di interi contenente n elementi ed un intero k, si vuole cancellare dall’array ogni occorrenza di k.
Ad esempio se l’array in questione contiene i sette elementi: (10,2,8,7,6,8,1) e l’elemento da cancellare è 8, l’array si trasformerà in (10,2,7,6,1).
Sappiamo che ogni volta che si deve eliminare un elemento da un array occorre spostare tutti gli elementi che lo seguono di un posto verso l’alto.
Nel nostro caso, però, per cancellare il primo 8 è inutile spostare verso l’alto il secondo 8 che comunque dovrà essere in seguito cancellato.
L’idea è di ‘riscrivere’ l’array A a partire da un indice j inizialmente uguale a zero, inserendo in A[j] il primo elemento diverso da 8 che incontriamo e
incrementando j di una unità e ripetendo la stessa operazione per ogni elemento di A.
Parametri?
Driver di una function
Proviamo dunque a scrivere questa function: l’array A è evidentemente un parametro di input-output, k un parametro di input ed n, il numero di elementi presenti in A prima della cancellazione è un parametro di input- output.
Infatti se n venisse passato per valore non sapremmo più quanti elementi sono effettivamente rimasti in A dopo l’esecuzione della function.
Driver di una function
Per verificare se questa function si comporta correttamente basta scrivere un piccolo main, un driver, il cui corpo sarà del tipo:
void cancella(int k, int *n, int A[]) { int j=-1;
for(i=0;i<*n;i++) {
if (A[i] != k) {
j++; A[j]=A[i];
} }
*n=j+1;
}
…
for(i=0;i<n;i++)
printf(“%d ”,A[i]);
cancella(k,n,A)
printf(”elementi rimasti %d\n“,n);
for (I=0,I<n,I++)
printf(”%d /n”,A[I]);
…
driver: un main scritto con l’unico scopo di verificare se una function si comporta correttamente.
esercizio11.2.cpp
Driver di una function
Regola generale per la scrittura di un driver per una procedura.
Supponiamo che la definizione di procedura contenga come parametri di input x1,..,xn,
parametri di input-output y1,…,ym parametri di output z1,…zr.
Allora il corpo del driver sarà:
cin>>x1>>…>>xn>>y1>>…>>ym;
f(x1,…,xn,y1,…,ym,z1,…,zr);
cout<<y1<<…<<ym<<z1…<<zr;
In altri termini il driver leggerà tutti i parametri di input e di input-output e stamperà tutti i parametri di input-output e di output.
Nel caso invece di una funzione del tipo:
float f(x1,x2,…,xn);
il corpo del driver sarà:
cin>>x1>>…>>xn ; cout<<f(x1,x2,…xn);
Equazioni di 2
ogrado
Problema
Assegnata la generica equazione di 2° grado Ax2 + Bx + C = 0
dove A, B e C sono numeri reali trovare le soluzioni.
A 2
AC 4
B B +
2- -
A 2
AC 4
B B -
2- -
Chiamiamo discriminante il valore della espressione
AC 4
B 2 -
=
D
Esempio: calcolo delle radici di un’equazione di 2o grado a x2 + b x + c = 0
Input: i coefficenti a, b, e c Output:
a = 0 - non quadratica
b=c=0 à indeterminata
b=0, c¹0 à c=0 equazione impossibile
b¹0, c¹0 à equazione lineare con soluzione x= -C/B
a ¹ 0 - quadratica degenere: B=0 e/o C=0
b=0, c=0 à monomia ax2 = 0; ammette una soluzione (doppia) x1=2 = 0 b=0, c¹0 à pura ax2 + c = 0; ammette due soluzioni: x2/1 = ± √-C/A
b¹0, c=0 à spuria x(ax + b) = 0; ammette due soluzioni: x1=0 e x2=-B/A
a ¹ 0 - quadratica completa: B¹0 e C¹0 (Δ = b
2– 4ac)
Δ > 0 à ammette due soluzioni reali distinte
Δ = 0 à ammette due soluzioni reali coincidenti: -B/2A Δ < 0 à ammette due soluzioni immaginarie distinte
Equazioni di 2
ogrado
Esempio: calcolo delle radici di un’equazione di 2
ogrado a x
2+ b x + c = 0
Il primo, caratterizzato da a=0, porta all’equazione di primo grado, equazione non quadratica, mentre gli altri due casi si distinguono dal valore di c o b, nullo per l’equazione quadratica degenere, tutti diversi da zero nel caso dell’equazione con due radici.
Se il coefficiente a è nullo
risolvi l’equazione non quadratica altrimenti
se c o b è nullo
l’equazione è degenere
altrimenti è un’equazione con due radici
Equazioni di 2
ogrado
leggi(a,b,c) if (a = 0):
nonquadratica(b,c) else:
if (b = 0 or c = 0):
incompleta(a,b,c) else:
completa(a,b,c)
Equazioni di 2
ogrado
leggi(a,b,c) if (a = 0):
nonquadratica(b,c) else:
if (b = 0 or c = 0):
incompleta(a,b,c) else:
completa(a,b,c) function nonquadratica(b,c):
if (b = 0):
if (c = 0):
stampa(“indeterminata”) else:
stampa(“impossibile”) else:
stampa(“lineare”) x1 ß -c/b
stampa(x1) return:
Equazioni di 2
ogrado
function nonquadratica(b,c):
if (b = 0):
if (c = 0):
stampa(“indeterminata”) else:
stampa(“impossibile”) else:
stampa(“lineare”) x1 ß -c/b
stampa(x1) return:
leggi(a,b,c) if (a = 0):
nonquadratica(b,c) else:
if (b = 0 or c = 0):
incompleta(a,b,c) else:
completa(a,b,c) function incompleta(a,b,c):
if (b = 0):
if (c = 0):
stampa(“monomia”) x1 ß x2 ß 0
else:
stampa(“pura”) x1 ß -Ö(c/a) x2 ß +Ö(c/a) else:
stampa(“spuria”) x1 ß 0
x2 ß -b/2a stampa(x1,x2) return:
Equazioni di 2
ogrado
leggi(a,b,c) if (a = 0):
nonquadratica(b,c) else:
if (b = 0 or c = 0):
incompleta(a,b,c) else:
completa(a,b,c) function nonquadratica(b,c):
if (b = 0):
if (c = 0):
stampa(“indeterminata”) else:
stampa(“impossibile”) else:
stampa(“lineare”) x1 ß -c/b
stampa(x1) return:
function incompleta(a,b,c):
if (b = 0):
if (c = 0):
stampa(“monomia”) x1 ß x2 ß 0
else:
stampa(“pura”) x1 ß -Ö(c/a) x2 ß +Ö(c/a) else:
stampa(“spuria”) x1 ß 0
x2 ß -b/2a stampa(x1,x2) return:
function completa(a,b,c):
delta ß b2 – 4ac if (delta = 0):
stampa(“una radice reale doppia”) x12 ß -b/(2a)
stampa(x12) else:
if (delta > 0):
stampa(“due radici reali distinte”) x1 ß (-b – Ödelta)/(2a)
x2 ß (-b + Ödelta)/(2a) else:
stampa(“due radici immaginarie distinte”)
x1 ß (-b – iÖdelta)/(2a) x2 ß (-b + iÖdelta)/(2a) stampa(x1,x2)
return:
esercizio11.3.cpp