[C++] Invertire un vettore
Ciao a tutti, qualcuno può dirmi cosa non va bene (immagino moolte cose
) con questo programma che in teoria dovrebbe invertire un vettore?

#include <iostream> using namespace std; int main(){ int v[10]; int n; cout << "Inserire quanti elementi si desidera allocare nel vettore, in numero inferiore a 100." << endl; cin >> n; if (n<10) cout << "Ok, procediamo!" << endl; else cout << "Dato non valido. Inserire un nuovo dato." << endl; for (int index=0; index<n; index++) cout << "Inserire valori dell'array" << endl; cin >> v[index]; for(int i=0; i<n; i++) v[i]=v[n-i]; // questa missà che l'ho sparata grossa, ma ci ho provato ugualmente... return 0; }
Risposte
Ciao, è necessario un array d'appoggio. L'ultimo ciclo for diventerebbe:
int j = 0; for(int i = n - 1; i > 0; i++){ arrayDue[j] = v[i]; j++; }
Ecco la soluzione che ho fatto io:
#include <iostream> using namespace std; int main(){ int v[10]; int n; int temp; cout << "Inserire quanti elementi si desidera allocare nel vettore, in numero inferiore a 10." << endl; cin >> n; if (n<10) cout << "Ok, procediamo!" << endl; else cout << "Dato non valido. Inserire un nuovo dato." << endl; for (int index=0; index<n; index++){ cout << "Inserire valori dell'array" << endl; cin >> v[index]; } for(int i=0; i<(n-i); i++){ temp = v[i]; v[i]=v[n-i-1]; v[n-i-1] = temp; } for(int i=0; i<n; i++) cout << v[i]; return 0; }
Ciao, grazie per la risposta! Faccio mea culpa: nel testo dell'esercizio è riportato esplicitamente che è vietato usare array d'appoggio 
Vi ringrazio molto per le soluzioni alternative, ma vorrei capire perché il mio ultimo ciclo è problematico! Me lo sapreste spiegare?

Vi ringrazio molto per le soluzioni alternative, ma vorrei capire perché il mio ultimo ciclo è problematico! Me lo sapreste spiegare?

Nel codice da te postato ci sono effettivamente molte cose che non vanno bene:
- innanzitutto non compila perchè nella riga
cin >> v[index];
la variabile index non risulta dichiarata. Il motivo è che non utilizzi le parentesi graffe per racchiudere il corpo del primo ciclo for. Le parentesi si possono anche omettere, ma in quel caso il corpo del ciclo sarà costituito solo dalla prima istruzione successiva al for (stessa cosa vale anche per if, while, else, ecc...). In ogni caso ti consiglio per una questione di leggibilità e chiarezza di usare sempre le parentesi graffe, anche quando l'istruzione è unica;
- sempre per una questione di leggibilità e chiarezza ti consiglio anche di scrivere codice in modo indentato;
- prima dichiari un array di 10 int e poi dici che il numero di elementi debba essere inferiore a 100. Il 100 al posto del 10 sarà sicuramente un errore di distrazione (infatti nell'if successivo torni ad utilizzare il 10), ma invece dire che n deve essere minore di 10 è un errore vero e proprio, perchè se la capienza dell'array è 10 anche 10 è un valore accettabile. Quindi la condizione dell'if deve essere n < 11;
- il costrutto if/else da te utilizzato non funziona in questo caso, infatti se inserisci un valore di n non valido il programma continua normalmente e non dà la possibilità di inserire un nuovo valore di n. Il costrutto che utilizzerei in questo caso è un do/while;
- per quanto riguarda il secondo for se ci pensi ti renderai conto che senza l'utilizzo di un "appoggio" la perdita di dati è inevitabile. Inoltre un array di appoggio è superfluo in quanto il problema può essere risolto utilizzando una semplice variabile d'appoggio. Visto che chiedi perchè il ciclo da te scritto non va bene, vediamo cosa succede partendo dall'inizio. Ipotizzando che n=5 avremo che per i=0 l'istruzione diventerà v[0]=v[5]. A questo punto i problemi sono due: il valore contenuto in v[0] è andato perduto irrimediabilmente ed è stato sostituito da un valore casuale in quanto v[5] si trova al di fuori del range dell'array (l'ultimo elemento infatti è v[4]). Risulta quindi inutile continuare con i=1,2,3,4;
- il return 0 è superfluo.
Dopo nel caso ti posto il modo in cui io avrei risolto l'esercizio.
EDIT:
Se hai dubbi chiedi pure.
- innanzitutto non compila perchè nella riga
cin >> v[index];
la variabile index non risulta dichiarata. Il motivo è che non utilizzi le parentesi graffe per racchiudere il corpo del primo ciclo for. Le parentesi si possono anche omettere, ma in quel caso il corpo del ciclo sarà costituito solo dalla prima istruzione successiva al for (stessa cosa vale anche per if, while, else, ecc...). In ogni caso ti consiglio per una questione di leggibilità e chiarezza di usare sempre le parentesi graffe, anche quando l'istruzione è unica;
- sempre per una questione di leggibilità e chiarezza ti consiglio anche di scrivere codice in modo indentato;
- prima dichiari un array di 10 int e poi dici che il numero di elementi debba essere inferiore a 100. Il 100 al posto del 10 sarà sicuramente un errore di distrazione (infatti nell'if successivo torni ad utilizzare il 10), ma invece dire che n deve essere minore di 10 è un errore vero e proprio, perchè se la capienza dell'array è 10 anche 10 è un valore accettabile. Quindi la condizione dell'if deve essere n < 11;
- il costrutto if/else da te utilizzato non funziona in questo caso, infatti se inserisci un valore di n non valido il programma continua normalmente e non dà la possibilità di inserire un nuovo valore di n. Il costrutto che utilizzerei in questo caso è un do/while;
- per quanto riguarda il secondo for se ci pensi ti renderai conto che senza l'utilizzo di un "appoggio" la perdita di dati è inevitabile. Inoltre un array di appoggio è superfluo in quanto il problema può essere risolto utilizzando una semplice variabile d'appoggio. Visto che chiedi perchè il ciclo da te scritto non va bene, vediamo cosa succede partendo dall'inizio. Ipotizzando che n=5 avremo che per i=0 l'istruzione diventerà v[0]=v[5]. A questo punto i problemi sono due: il valore contenuto in v[0] è andato perduto irrimediabilmente ed è stato sostituito da un valore casuale in quanto v[5] si trova al di fuori del range dell'array (l'ultimo elemento infatti è v[4]). Risulta quindi inutile continuare con i=1,2,3,4;
- il return 0 è superfluo.
Dopo nel caso ti posto il modo in cui io avrei risolto l'esercizio.
EDIT:
#include <iostream> using namespace std; int main() { int v[10]; int n; int temp; do { cout << "Inserire quanti elementi si desidera allocare nel vettore (max 10): "; cin >> n; } while(n > 10); for(int i = 0; i < n; i++) { cout << "v[" << i << "] = "; cin >> v[i]; } for(int i = 0; i < n / 2; i++) { temp = v[i]; v[i] = v[n - i - 1]; v[n - i - 1] = temp; } for(int i = 0; i < n; i++) { cout << v[i] << " "; } }
Se hai dubbi chiedi pure.
Inoltre mi permetto di dire che utilizzare un array di appoggio, seppur in questo caso piccolo perché di dimensione 10, è un inutile spreco di memoria. In casi come questi la miglior soluzione è utilizzare una variabile di appoggio che ti rende meno dispendioso sia il tempo di esecuzione che la quantità di memoria usata.
Per quanto riguarda l'assegnazione di un valore a una variabile, nel momento che viene eseguita l'istruzione A = B, il valore di A viene perso del tutto, poiché stai proprio sovrascrivendo il valore di A con quello di B, quindi già all'inizio del ciclo ti trovi l'array con valore iniziale e finale coincidenti.
Comunque posso capire la tua difficoltà, anche io quando ho iniziato non mi capacitavo di queste cose ma con un bel po' di pratica vedrai che non è cosi difficile come sembra.
Per quanto riguarda l'assegnazione di un valore a una variabile, nel momento che viene eseguita l'istruzione A = B, il valore di A viene perso del tutto, poiché stai proprio sovrascrivendo il valore di A con quello di B, quindi già all'inizio del ciclo ti trovi l'array con valore iniziale e finale coincidenti.
Comunque posso capire la tua difficoltà, anche io quando ho iniziato non mi capacitavo di queste cose ma con un bel po' di pratica vedrai che non è cosi difficile come sembra.

Ti ringrazio per la risposta esaustiva! So che col tempo ci si prende la mano, ma io ho iniziato due giorni fa e ho un appello tra una settimana
non chiedermi perché mi sia tirato così in ritardo! [strike](gli altri esami)[/strike]
Comunque, sì, il cento è un errore dovuto al fatto che inizialmente pensavo di usare un vettore più grande, e modificando in seguito mi sono perso un pezzo. Hai ragione sull'errore 10-11, lì proprio non ci ho pensato.
Sul difetto del costrutto if-else avevo ragionato ma non riuscivo a trovare un'alternativa... mi ero dimenticato del do-while! Quindi praticamente ogni volta che ho una condizione che deve essere rispettata posso usare tale ciclo per garantire che l'utente inserisca dati validi, giusto? Ricordando come giustamente dici le parentesi graffe...
Nel tuo codice: il primo costrutto do-while serve a far sì che l'utente inserisca un dato corretto, cioè il numero di dati (sempre minore di dieci) che desidera inserire. Dopodiché scrivi un primo ciclo for che faccia vedere all'utente v così che possa inserire uno per uno i dati; un secondo ciclo for in cui memorizzi in una variabile temporanea ogni v per i che va da $0$ a $n/2$, imponi che tale v sia uguale v[n-i-1] (quel meno uno lo metti perchè inizialmente i vale 0, giusto? E quindi è "in ritardo" di una unità... non ci avrei mai pensato da solo
) e poi memorizzi quest'ultimo valore in temp.
Infine stampi il tutto con un ultimo ciclo for.
Se non ho interpretato male, ho capito il tuo codice e perché funziona; l'unica cosa che non mi è molto chiara è perché è necessario dichiarare una variabile di appoggio, temp: non si può ingenuamente uguagliare direttamente la posizione del vettore con quella a cui voglio associarla? E' una questione di chiarezza o è imprescindibile?
Grazie mille per le risposte comunque!

Comunque, sì, il cento è un errore dovuto al fatto che inizialmente pensavo di usare un vettore più grande, e modificando in seguito mi sono perso un pezzo. Hai ragione sull'errore 10-11, lì proprio non ci ho pensato.
Sul difetto del costrutto if-else avevo ragionato ma non riuscivo a trovare un'alternativa... mi ero dimenticato del do-while! Quindi praticamente ogni volta che ho una condizione che deve essere rispettata posso usare tale ciclo per garantire che l'utente inserisca dati validi, giusto? Ricordando come giustamente dici le parentesi graffe...
Nel tuo codice: il primo costrutto do-while serve a far sì che l'utente inserisca un dato corretto, cioè il numero di dati (sempre minore di dieci) che desidera inserire. Dopodiché scrivi un primo ciclo for che faccia vedere all'utente v così che possa inserire uno per uno i dati; un secondo ciclo for in cui memorizzi in una variabile temporanea ogni v per i che va da $0$ a $n/2$, imponi che tale v sia uguale v[n-i-1] (quel meno uno lo metti perchè inizialmente i vale 0, giusto? E quindi è "in ritardo" di una unità... non ci avrei mai pensato da solo

Infine stampi il tutto con un ultimo ciclo for.
Se non ho interpretato male, ho capito il tuo codice e perché funziona; l'unica cosa che non mi è molto chiara è perché è necessario dichiarare una variabile di appoggio, temp: non si può ingenuamente uguagliare direttamente la posizione del vettore con quella a cui voglio associarla? E' una questione di chiarezza o è imprescindibile?
Grazie mille per le risposte comunque!
Di niente.
Tutto giusto cmq.
Fare esempi su carta è sempre un ottimo modo per risolvere questo genere di problemi.
Provo a spiegarti il ragionamento che mi ha portato a scrivere quel codice. Invertire un vettore significa scambiare gli elementi del vettore con i rispettivi simmetrici rispetto al centro dell'array (che coincide con l'elemento centrale nel caso in cui il numero di elementi sia dispari, e con lo "spazio" tra i due elementi centrali nel caso in cui il numero di elementi sia pari). Quindi al fine di invertire l'array basta scambiare gli elementi che si trovano prima del centro dell'array, infatti se con l'indice i invece di fermarci a n/2 andassimo oltre fino ad n torneremmo a scambiare gli elementi riottenendo l'array di partenza. Per verificare la correttezza della condizione i
Per quanto riguarda il meno uno non è tanto difficile arrivarci, per esempio per n=5 avremo che il primo elemento di indice 0 dovrà essere scambiato con l'ultimo che ha indice 4. Come possiamo da n=5 e i=0 ottenere 4? 4=n-i-1. A quel punto basta verificare la correttezza di questa soluzione per i=1,2,...
E' imprescindibile e adesso ti spiego il perchè. Immagina di avere due variabili x=0 e y=1, e di volerne scambiare il contenuto. Nel C++ non esiste un comando base per scambiare il contenuto di due variabili, bisogna quindi procedere per assegnazioni successive. Ora con le sole variabili x e y le uniche assegnazioni possibili sono x=y (quindi x=y=1) e y=x (quindi x=y=0), ma in entrambi i casi perderemo uno dei valori contenuti nelle variabili. Risulta quindi indispensabile l'utilizzo di una terza variabile d'appoggio che conservi temporaneamente il valore contenuto in una delle due variabili e che eviti quindi la perdita di dati.
Immagina per esempio avere un bicchiere d'acqua e uno di aranciata e di volerne scambiare il contenuto. Risulta evidente in questo caso che l'utilizzo di un terzo contenitore diventa indispensabile.

Tutto giusto cmq.
un secondo ciclo for in cui memorizzi in una variabile temporanea ogni v per i che va da 0 a n2, imponi che tale v sia uguale v[n-i-1] (quel meno uno lo metti perchè inizialmente i vale 0, giusto? E quindi è "in ritardo" di una unità... non ci avrei mai pensato da solo) e poi memorizzi quest'ultimo valore in temp.
Fare esempi su carta è sempre un ottimo modo per risolvere questo genere di problemi.
Provo a spiegarti il ragionamento che mi ha portato a scrivere quel codice. Invertire un vettore significa scambiare gli elementi del vettore con i rispettivi simmetrici rispetto al centro dell'array (che coincide con l'elemento centrale nel caso in cui il numero di elementi sia dispari, e con lo "spazio" tra i due elementi centrali nel caso in cui il numero di elementi sia pari). Quindi al fine di invertire l'array basta scambiare gli elementi che si trovano prima del centro dell'array, infatti se con l'indice i invece di fermarci a n/2 andassimo oltre fino ad n torneremmo a scambiare gli elementi riottenendo l'array di partenza. Per verificare la correttezza della condizione i
l'unica cosa che non mi è molto chiara è perché è necessario dichiarare una variabile di appoggio, temp: non si può ingenuamente uguagliare direttamente la posizione del vettore con quella a cui voglio associarla? E' una questione di chiarezza o è imprescindibile?
E' imprescindibile e adesso ti spiego il perchè. Immagina di avere due variabili x=0 e y=1, e di volerne scambiare il contenuto. Nel C++ non esiste un comando base per scambiare il contenuto di due variabili, bisogna quindi procedere per assegnazioni successive. Ora con le sole variabili x e y le uniche assegnazioni possibili sono x=y (quindi x=y=1) e y=x (quindi x=y=0), ma in entrambi i casi perderemo uno dei valori contenuti nelle variabili. Risulta quindi indispensabile l'utilizzo di una terza variabile d'appoggio che conservi temporaneamente il valore contenuto in una delle due variabili e che eviti quindi la perdita di dati.
Immagina per esempio avere un bicchiere d'acqua e uno di aranciata e di volerne scambiare il contenuto. Risulta evidente in questo caso che l'utilizzo di un terzo contenitore diventa indispensabile.
Il c++ definisce la funzione std::swap in utility. Prima del c++11 era in algorithm.
Detto questo, siccome si tratta di interi esiste un modo per scambiarli senza l'uso di variabili di appoggio. D'altra parte il compilatore generalmente rimuove la variabile di appoggio e fa lo scambio usando i registri. Pertanto l'uso esplicito di questo metodo non è generalmente né più veloce né più leggibile (potrebbe persino impedire al compilatore di ottimizzare quella parte).
Detto questo, siccome si tratta di interi esiste un modo per scambiarli senza l'uso di variabili di appoggio. D'altra parte il compilatore generalmente rimuove la variabile di appoggio e fa lo scambio usando i registri. Pertanto l'uso esplicito di questo metodo non è generalmente né più veloce né più leggibile (potrebbe persino impedire al compilatore di ottimizzare quella parte).
Vict, non ti ho seguito, mi spiace.
Squirrel, ho compreso perfettamente, grazie mille. L'analogia del travaso è vincente
Squirrel, ho compreso perfettamente, grazie mille. L'analogia del travaso è vincente

Quello che intendevo è mostrato in questa codice:
#include <utility> #include <iostream> int main(void) { int A[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; std::cout << "Array iniziale = {"; std::cout << A[0]; for (int i = 1; i != 10; ++i) { std::cout << ", " << A[i]; } std::cout << "}" << std::endl; for (int i = 0; i != 5; ++i) { // questa e' la funzione standard per // fare lo scambio di elementi std::swap(A[i], A[9 - i]); } std::cout << "Array invertito = {"; std::cout << A[0]; for (int i = 1; i != 10; ++i) { std::cout << ", " << A[i]; } std::cout << "}" << std::endl; for (int i = 0; i != 5; ++i) { // questo e' un metodo che non usa // variabili d'appoggio A[i] ^= A[9 - i]; A[9 - i] ^= A[i]; A[i] ^= A[9 - i]; } std::cout << "Array ri-invertito = {"; std::cout << A[0]; for (int i = 1; i != 10; ++i) { std::cout << ", " << A[i]; } std::cout << "}" << std::endl; }
Ciao vict, grazie per esserti preso il disturbo. Una domanda veloce sul tuo codice: perché scrivi std:: ogni volta anziché usare namespace std? Sono curioso...
Usare namespace std inserisce i nomi del namespace sdt all'interno del namespace in cui ti trovi. Quindi perdi un po' il senso di avere un namespace. Inoltre rischi che in quel namespace sia definita una funzione o una classe con lo stesso nome. Con cose come cout è raro, ma le funzioni come swap o le classi come vector o map lo sono molto meno.
"Super Squirrel":
Nel codice da te postato ci sono effettivamente molte cose che non vanno bene:
- innanzitutto non compila perchè nella riga
cin >> v[index];
la variabile index non risulta dichiarata. Il motivo è che non utilizzi le parentesi graffe per racchiudere il corpo del primo ciclo for. Le parentesi si possono anche omettere, ma in quel caso il corpo del ciclo sarà costituito solo dalla prima istruzione successiva al for (stessa cosa vale anche per if, while, else, ecc...). In ogni caso ti consiglio per una questione di leggibilità e chiarezza di usare sempre le parentesi graffe, anche quando l'istruzione è unica;
- sempre per una questione di leggibilità e chiarezza ti consiglio anche di scrivere codice in modo indentato;
- prima dichiari un array di 10 int e poi dici che il numero di elementi debba essere inferiore a 100. Il 100 al posto del 10 sarà sicuramente un errore di distrazione (infatti nell'if successivo torni ad utilizzare il 10), ma invece dire che n deve essere minore di 10 è un errore vero e proprio, perchè se la capienza dell'array è 10 anche 10 è un valore accettabile. Quindi la condizione dell'if deve essere n < 11;
- il costrutto if/else da te utilizzato non funziona in questo caso, infatti se inserisci un valore di n non valido il programma continua normalmente e non dà la possibilità di inserire un nuovo valore di n. Il costrutto che utilizzerei in questo caso è un do/while;
- per quanto riguarda il secondo for se ci pensi ti renderai conto che senza l'utilizzo di un "appoggio" la perdita di dati è inevitabile. Inoltre un array di appoggio è superfluo in quanto il problema può essere risolto utilizzando una semplice variabile d'appoggio. Visto che chiedi perchè il ciclo da te scritto non va bene, vediamo cosa succede partendo dall'inizio. Ipotizzando che n=5 avremo che per i=0 l'istruzione diventerà v[0]=v[5]. A questo punto i problemi sono due: il valore contenuto in v[0] è andato perduto irrimediabilmente ed è stato sostituito da un valore casuale in quanto v[5] si trova al di fuori del range dell'array (l'ultimo elemento infatti è v[4]). Risulta quindi inutile continuare con i=1,2,3,4;
- il return 0 è superfluo.
Dopo nel caso ti posto il modo in cui io avrei risolto l'esercizio.
EDIT:
#include <iostream> using namespace std; int main() { int v[10]; int n; int temp; do { cout << "Inserire quanti elementi si desidera allocare nel vettore (max 10): "; cin >> n; } while(n > 10); for(int i = 0; i < n; i++) { cout << "v[" << i << "] = "; cin >> v[i]; } for(int i = 0; i < n / 2; i++) { temp = v[i]; v[i] = v[n - i - 1]; v[n - i - 1] = temp; } for(int i = 0; i < n; i++) { cout << v[i] << " "; } }
Se hai dubbi chiedi pure.
Ciao guardavo la tua soluzione, non capisco all'interno di "for(int i = 0; i < n / 2; i++)" perchè e cosa significa i< n/2.
Ti ringrazio.
"mpg":
Ciao guardavo la tua soluzione, non capisco all'interno di "for(int i = 0; i < n / 2; i++)" perchè e cosa significa i< n/2.
Ti ringrazio.
Il codice C raramente cambia significato a seconda di dove lo vedi. Se fosse stato
int m = n/2; for(int i =0; i<m; i++)ti sarebbe stato più chiaro?
"vict85":
[quote="mpg"]Ciao guardavo la tua soluzione, non capisco all'interno di "for(int i = 0; i < n / 2; i++)" perchè e cosa significa i< n/2.
Ti ringrazio.
Il codice C raramente cambia significato a seconda di dove lo vedi. Se fosse stato
int m = n/2; for(int i =0; i<m; i++)ti sarebbe stato più chiaro?[/quote]
No non mi sono spiegato bene io, non capisco perchè metti n/2 che funzione avrebbe in questo contesto scusami non sono ancora superferrato..
Ho letto a metà del thread la spiegazione di Squirrel, non ci sarei mai arrivato, caspita!!
"Super Squirrel":
E' imprescindibile e adesso ti spiego il perchè. Immagina di avere due variabili x=0 e y=1, e di volerne scambiare il contenuto. Nel C++ non esiste un comando base per scambiare il contenuto di due variabili, bisogna quindi procedere per assegnazioni successive. Ora con le sole variabili x e y le uniche assegnazioni possibili sono x=y (quindi x=y=1) e y=x (quindi x=y=0), ma in entrambi i casi perderemo uno dei valori contenuti nelle variabili. Risulta quindi indispensabile l'utilizzo di una terza variabile d'appoggio che conservi temporaneamente il valore contenuto in una delle due variabili e che eviti quindi la perdita di dati.
Immagina per esempio avere un bicchiere d'acqua e uno di aranciata e di volerne scambiare il contenuto. Risulta evidente in questo caso che l'utilizzo di un terzo contenitore diventa indispensabile.
Su due variabili è possibile fare molte più operazioni che assegnare loro un valore. Prendiamo per esempio due valori interi (con infinita precisione per il momento). Se facciamo le seguenti operazioni:
x <- x + y y <- x - y x <- x - y
Avremo che alla fine le due variabili sono state scambiate. Se chiamiamo infatti ogni nuova versione diversamente abbiamo che:
x1 = x + y y1 = x1 - y x2 = x1 - y1
Abbiamo che y1 vale x1 - y e quindi x + y - y = x. In modo simile, x2 è uguale a x1 - y1 e quindi a x + y - x = y. Alla fine di queste operazioni avremo quindi scambiato le due variabili. Lo stesso procedimento è possibile con ogni operazione binaria che possa essere invertita. In C++ l'operazione migliore per questa operazione è lo XOR bitwise (rappresentato con ^). Il tuo codice sarà quindi in questo caso:
x = x ^ y; y = x ^ y; x = x ^ y;
Il codice finale è però decisamente oscuro e in pratica più lento di quello che fa uso di una variabile intermedia. La ragione è principalmente che lo scambio può essere implementato come segue in un qualche pseudo-assembly:
MOV r0, [x] // sposto il valore in x nel registro r0 MOV r1, [y] // sposto il valore di y nel registro r1 MOV [x], r1 // sposto il valore in r1 in x MOV [y], r0 // sposto il valore in r0 in y
Nel caso degli XOR invece il codice avrà la seguente forma:
MOV r0, [x] // sposto il valore in x nel registro r0 MOV r1, [y] // sposto il valore in y nel registro r1 XOR r0, r0, r1 // faccio lo XOR tra r0 e r1 e memorizzo il valore in r0 XOR r1, r0, r1 // faccio lo XOR tra r0 e r1 e memorizzo il valore in r1 XOR r0, r0, r1 // faccio lo XOR tra r0 e r1 e memorizzo il valore in r0 MOV [x], r0 // sposto il valore di r0 in x MOV [y], r1 // sposto il valore di r1 in y
Quando si parla di C++ questo trucco è abbastanza inutile. Ha forse un senso in assembly per scambiare registri in situazioni in cui non ci sono altri registri liberi. Ma anche in questo caso fa più che altro parte del passato in cui il numero di registri era molto più limitato e comunque in situazioni molto più particolari. Credo sia poi utile per vedere come spesso sia possibile trovare soluzioni a problemi che sembravano irrisolvibili mettendo in dubbio le proprie convinzioni (che l'unica operazione utilizzabile per uno scambio fosse l'assegnazione di un valore ad esempio).