Passaggio dei parametri
Ciao ragazzi, qualcuno mi può aiutare con il seguente esercizio?
Dato il seguente programma in un linguaggio non meglio identificato, indicare cosa stampa il programma nel caso di:
1. parametri passati per valore;
2. parametri passati per riferimento;
3. parametri passati per valore-risultato
Io ho svolto l'esercizio nel seguente modo ma non sono sicura che sia corretto:
passaggio per valore:
il primo print stampa 1,3,10
il secondo print stampa 2,3,10
passaggio per riferimento
il primo print stampa 2,20,10
il secondo print stampa 3,100,102
passaggio per valore-risultato
il primo print stampa 2,20,10
il secondo print stampa 4,100,103
mi sapreste dire se è corretto o eventualmente quali errori ho commesso? Grazie!
Dato il seguente programma in un linguaggio non meglio identificato, indicare cosa stampa il programma nel caso di:
1. parametri passati per valore;
2. parametri passati per riferimento;
3. parametri passati per valore-risultato
int x=1; int w = 3; int z= 10; int f(int y){ y=20; throw E; return (x++) + y; } int g(int y){ y=100; try{ throw E; } catch E{ } return (x++) + y; } try{ f(w); } catch E{ } print (x,w,z); z = g(w); print (x,w,z);
Io ho svolto l'esercizio nel seguente modo ma non sono sicura che sia corretto:
passaggio per valore:
il primo print stampa 1,3,10
il secondo print stampa 2,3,10
passaggio per riferimento
il primo print stampa 2,20,10
il secondo print stampa 3,100,102
passaggio per valore-risultato
il primo print stampa 2,20,10
il secondo print stampa 4,100,103
mi sapreste dire se è corretto o eventualmente quali errori ho commesso? Grazie!
Risposte
Nel passaggio con valore hai sbagliato il valore di \(z\) a cui viene assegnato il valore di ritorno della funzione \(g\) che è uguale a \(x + y = 1 + 100 = 101 \neq 10.\)
Nel passaggio per riferimento il valore della \(x\) non viene modificata all'interno della funzione \(f\) (l'istruzione return non viene chiamata a causa della eccezione) e quindi avrà valore \(1\) e non \(2\) a primo [tt]print[/tt]. Avrà quindi valore \(1\) nella seconda funzione per cui il risultato sarà \( 2, 100, 101 \) e non quello che hai scritto.
Discorso del tutto simile vale per il passaggio per valore risultato che dovrebbe avere lo stesso risultato del passaggio per riferimento se non sbaglio.
Nota che la variabile \(x\) NON è un argomento della funzione e viene trattato nello stesso modo da tutti e tre i sistemi. L'unica variabile che viene trattata diversamente dai tre sistemi è la variabile \(w\) che viene modificata negli ultimi due sistemi ma non nel primo.
Nel passaggio per riferimento il valore della \(x\) non viene modificata all'interno della funzione \(f\) (l'istruzione return non viene chiamata a causa della eccezione) e quindi avrà valore \(1\) e non \(2\) a primo [tt]print[/tt]. Avrà quindi valore \(1\) nella seconda funzione per cui il risultato sarà \( 2, 100, 101 \) e non quello che hai scritto.
Discorso del tutto simile vale per il passaggio per valore risultato che dovrebbe avere lo stesso risultato del passaggio per riferimento se non sbaglio.
Nota che la variabile \(x\) NON è un argomento della funzione e viene trattato nello stesso modo da tutti e tre i sistemi. L'unica variabile che viene trattata diversamente dai tre sistemi è la variabile \(w\) che viene modificata negli ultimi due sistemi ma non nel primo.
Come piccola prova di quello che ti ho scritto, ecco un programma che risolve il problema dell'esercizio. L'unico programma che conosco rispettare tutti i tipi di passaggi che hai scritto è Chapel. Il programma per il passaggio per valore è il seguente:
Il passaggio per valore in questo linguaggio è caratterizzato dalla scritta [tt]in[/tt] prima dell'argomento. Il risultato compilando e lanciando questo programma (puoi usare questo sito per testarlo) è
Il passaggio per riferimento è caratterizzato dalla scritta [tt]ref[/tt] e il programma intero è
il risultato è
Infine il passaggio per valore-ritorno è ottenuto con la parola chiave [tt]inout[/tt].
Il risultato è lo stesso del passaggio per riferimento, cioè
var x: int = 1; var w: int = 3; var z: int = 10; proc f(in y: int): int throws { y = 20; throw new owned Error(); const res = x + y; x = x + 1; return res; } proc g(in y: int): int throws { y = 100; try { throw new owned Error(); } catch { } const res = x + y; x = x + 1; return res; } try { f(w); } catch { } writeln(x, " ", w, " ", z); z = g(w); writeln(x, " ", w, " ", z);
Il passaggio per valore in questo linguaggio è caratterizzato dalla scritta [tt]in[/tt] prima dell'argomento. Il risultato compilando e lanciando questo programma (puoi usare questo sito per testarlo) è
1 3 10 2 3 101
Il passaggio per riferimento è caratterizzato dalla scritta [tt]ref[/tt] e il programma intero è
var x: int = 1; var w: int = 3; var z: int = 10; proc f(ref y: int): int throws { y = 20; throw new owned Error(); const res = x + y; x = x + 1; return res; } proc g(ref y: int): int throws { y = 100; try { throw new owned Error(); } catch { } const res = x + y; x = x + 1; return res; } try { f(w); } catch { } writeln(x, " ", w, " ", z); z = g(w); writeln(x, " ", w, " ", z);
il risultato è
1 20 10 2 100 101
Infine il passaggio per valore-ritorno è ottenuto con la parola chiave [tt]inout[/tt].
var x: int = 1; var w: int = 3; var z: int = 10; proc f(inout y: int): int throws { y = 20; throw new owned Error(); const res = x + y; x = x + 1; return res; } proc g(inout y: int): int throws { y = 100; try { throw new owned Error(); } catch { } const res = x + y; x = x + 1; return res; } try { f(w); } catch { } writeln(x, " ", w, " ", z); z = g(w); writeln(x, " ", w, " ", z);
Il risultato è lo stesso del passaggio per riferimento, cioè
1 20 10 2 100 101