• Non ci sono risultati.

C funzioni à argomenti

N/A
N/A
Protected

Academic year: 2021

Condividi "C funzioni à argomenti"

Copied!
44
0
0

Testo completo

(1)

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

(2)

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.

(3)

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.

(4)

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

(5)

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

(6)

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).

(7)

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

(8)

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).

(9)

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

(10)

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 diattivazione

void foo(...) { } ...

foo

main { } ...

ritorno

(11)

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 {

(12)

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 {

(13)

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.

(14)

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.

(15)

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);

(16)

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.

(17)

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

(18)

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)

(19)

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.

(20)

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

(21)

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

¹

0

Post: b intero >0

(22)

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

(23)

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

(24)

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:

(25)

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à

(26)

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

(27)

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 Istruzioni

Calcola quante monete servono da 50 cent Calcola quante monete servono da 20 cent

………

Stampa i risultati

(28)

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”);

}

(29)

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 */

}

(30)

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

(31)

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;

}

(32)

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)

(33)

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

(34)

C funzioni à argomenti array

Nel caso di passaggio di parametri come singoli elementi di un array non ci sono eccezioni alla regola generale

Esempio:

(35)

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?

(36)

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.

(37)

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

(38)

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);

(39)

Equazioni di 2

o

grado

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

(40)

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

o

grado

(41)

Esempio: calcolo delle radici di un’equazione di 2

o

grado 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

o

grado

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)

(42)

Equazioni di 2

o

grado

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:

(43)

Equazioni di 2

o

grado

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:

(44)

Equazioni di 2

o

grado

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

Riferimenti

Documenti correlati

VARIABILI LOCALI, cioè sono “note” (utilizzabili) solo all’interno delle funzione nella quale sono state definite Anche i parametri di una funzione sono variabili locali!.. C

Come il nome di un array equivale a un puntatore, così un array di puntatori equivale a un puntatore a puntatore (con in più l’allocazione della memoria puntata, come nel caso di

Generalizzando l’esempio, se indichiamo con V i il valore della grandezza totale (300 euro), con V f il valore finale (la percentuale 36 euro), con t il tasso percentuale,

• Regola 3: Anche se le stringhe di formato della scanf() assomigliano molto a quelle della printf(), hanno una semantica leggermente differente (leggete il manuale!). • Regola

whose name is distinct from all other existing files, and opens the file for binary writing and reading (as if the mode string &#34;wb+&#34; were used in an fopen() call). If

Osservazione : Valgono le stesse considerazioni fatte per il teorema precedente , cioè il limite della differenza di due funzioni può condurre alla forma indeterminata + ∞

Test sulla media di una popolazione normale (casi di varianza nota e non nota).. Test

[r]