Procedure - Funzioni Procedure e funzioni Parti di programma a cui è associato un nome e che può essere attivata mediante una chiamata. Le funzioni a differenza delle procedure restituisco un valore. Scrivere un programma che legge da input le misure dei lati di tre diversi parallelepipedi e ne calcoli il volume: vol1 := largh1 * prof1 * alt1 vol2 := largh2 * prof2 * alt2 vol3 := largh3 * prof3 * alt3 Cosa usereste per leggere i valori e per calcolare il volume? Procedura o funzione? Parametri Parametri formali: sono quelli specificati nell’intestazione della procedura: Procedure p(x: char; var t: integer); Parametri attuali: sono quelli specificati al momento della chiamata, dopo il nome della procedura: p(a, b); I parametri attuali devono corrispondere, per numero e per tipo, ai parametri formali. Quindi a deve essere di tipo char e b di tipo integer. Passaggio dei parametri Per valore: Il parametro per valore è una variabile locale della procedura/funzione, che viene inizializzata, al momento della chiamata, con il valore fornito come parametro attuale, che può essere una variabile o anche un’espressione di tipo equivalente al parametro formale. Per indirizzo (o per riferimento): Il parametro attuale deve essere una variabile dello stesso tipo specificato per il parametro formale. Ogni operazione riguardante il parametro formale è applicata direttamente al parametro attuale. Il nome del parametro formale deve essere preceduto dalla parola chiave var. VAR larghezza, profondita, altezza, volume, i: integer; Procedure leggi (var larg, prof, alt:integer); BEGIN writeln('parallelepipedo ',i); write('inserire i valori della larghezza: '); readln(larg); write('inserire i valori della profondita'': '); readln(prof); write('inserire i valori dell''altezza: '); readln(alt); END; function calcolavolume (larg, prof, alt:integer):integer; BEGIN calcolavolume := larg * prof * alt; END; BEGIN for i:=1 to 3 do begin leggi (larghezza, profondita, altezza); WHILE (larghezza < 0) OR (profondita < 0) OR (altezza < 0) DO BEGIN write('Dati non corretti - Ripetere l''inserimento '); leggi (larghezza, profondita, altezza); END; volume:=calcolavolume(larghezza,profondita,altezza); writeln('Il volume del parallelepipedo e'' ', volume); writeln; end; readln; END. Passaggio per indirizzo Passaggio per valore Individuare le chiamate non corrette Procedure A (x: integer; var y,z: integer; w: char); Le variabili n, k, h sono di tipo integer, b è di tipo char. A (n+1, k, h, b) A (n, k+1, h, b) A(ord(b), k, h, chr(n)) A(k div h, k, h, chr(n)) A( k / h, k, h, chr(n)) Simulazione Si simuli “manualmente” l'esecuzione del seguente programma al fine di dedurre l'output prodotto. VAR x, y: integer; PROCEDURE piu5 (a: integer; VAR b: integer); BEGIN writeln ('All''inizio dell''esecuzione di piu5: ',a:4,b:4); a := a + 5; b := b + 5; writeln ('Alla fine dell''esecuzione di piu5: ',a:4,b:4) END; BEGIN x := 10; y := 20; piu5(x,y); writeln ('Al rientro, dopo l''esecuzione di piu5: ',x:4, y:4); readln; END. Inizializzazione nel main BEGIN x := 10; y := 20; piu5(x,y); writeln ('Al rientro, dopo l''esecuzione di piu5: ',x:4, y:4); readln; END. x 10 20 y Chiamata alla procedura: Piu5(x,y),dove x=10, y=20 x 10 a 10 b y 20 PROCEDURE piu5 (a: integer; VAR b: integer); BEGIN writeln ('All''inizio dell''esecuzione di piu5: ',a:4,b:4); a := a + 5; b := b + 5; writeln ('Alla fine dell''esecuzione di piu5: ',a:4,b:4) END; Quindi: writeln ('All''inizio dell''esecuzione di piu5: ',a:4,b:4); stampa All'inizio dell'esecuzione di piu5: 10 20 x 10 a 15 b y 25 Quindi: writeln ('Alla fine dell''esecuzione di piu5: ',a:4,b:4) stampa Alla fine dell'esecuzione di piu5: 15 25 Infine: writeln('Al rientro, dopo l''esecuzione di piu5: ',x:4, y:4); stampa Al rientro, dopo l''esecuzione di piu5: 10 25 program EC; {$APPTYPE CONSOLE} uses SysUtils; var b, ris: integer; Function doppio(Var a: integer): integer; begin a:=2*a; doppio:=a; end; begin b:=3; ris:=2* doppio (b); writeln('Primo risultato: ', ris); Cosa stampa? writeln; b:=3; ris:= doppio (b) + doppio (b); writeln ('Secondo risultato: ', ris); readln; end. Cosa stampa? Primo risultato: ris:=2*doppio (B) B3 A B 6 A B3 Function doppio (Var a: integer): integer; begin a:=2*a; doppio:=a; end; La funzione doppio(b) = 2 ris = 2 * 6 = 12 Quindi writeln('Primo risultato: ', ris); stampa Primo risultato: 12 Secondo risultato: ris:=doppio(B)+doppio(B) B 3 A B 3 A B 6 La funzione doppio(B) = 6 B6 A B 6 La funzione doppio(B) = 12 Function doppio (Var a: integer): integer; begin a:=2*a; doppio:=a; end; Ris = 6 + doppio(B) A B 12 Risultato = 6 + 12 = 18 Var a, b: integer; Procedure Proc1 (var x,y: integer; c: integer); var aus: integer; Procedure Proc2 (var v,z: integer; c: integer); begin v:=v+c; Somma a v e z il valore c=5 z:=z+c; end; begin aus:=x; x:=y; y:=aus; Proc2(x,y,c); end; Scambia x e y begin write ('Digita il primo numero: '); readln (a); write ('Digita il secondo numero: '); readln (b); Proc1(a,b,5) writeln('Il primo numero e'': ',a); writeln('Il secondo numero e'': ',b); readln; end. Cosa succede quando chiamo: Proc1 (a, b, 5) ?????? Se a=4, b=6 Si ha a = 11 b= 9 Esercizio: permutazione random Dato un un numero intero n, costruire una procedura che generi una permutazione random di n elementi. Di cosa necessitiamo? Random(numero): funzione che ritorna un numero random nell’intervallo 0 <= X < numero. Se numero non è specificato, restituisce un valore reale nell’intervallo 0<= X < 1. E se volessi generare un numero 1 <= X <= numero? Randomize: procedura che inizializza il generatore di numeri random utilizzando un valore random ottenuto dal clock di sistema. Procedura Procedure permRandom (var A: tipoArray); Var i: integer; begin for i:=1 to n do p[i]:=i; for i:=n downto 2 do begin x:= random(i)+1; //Deve generare 1 <= x <= i scambia (v[i], v[x]); end; end; Esempio: n=4 0 0 0 0 1 2 3 4 1 2 3 4 1 2 3 4 for i:=1 to n do p[i]:=i; i=4, x=random(4)+1= 2 Scambia(v[4], v[2]) i=3, x=random(3)+1= 2 Scambia(v[3], v[2]) i=2, x=random(2)+1= 1 La permutazione random è for i:=n downto 2 do begin x:= random(i)+1; scambia (v[i], v[x]); end; Scambia(v[2], v[1]) 3 1 4 2 1 2 3 4 1 4 3 2 1 2 3 4 1 3 4 2 1 2 3 4 3 1 4 2 1 2 3 4 Esercizio 2 Data un numero intero n, costruire una procedura che generi una permutazione random di n elementi e la disponga in una matrice 4x4. Esempio: gioco del 15. Il 16 corrisponde alla casella vuota. 1 2 3 4 6 12 16 11 5 6 7 8 5 8 9 10 11 12 13 14 15 16 10 7 9 15 1 4 14 3 2 13