[C++]Esercizio scambio di variabili

jorja92
Mi potete aiutare, o dire dove sbaglio, in questo esercizio (come ho scritt nel titolo, finora abbiamo fatto solo variabili di tipo int):
Il testo dell'esercizio è questo:
Scrivere un programma che legge in ingresso due valori interi e li memorizza in due variabili e lo stampa sullo schermo, quindi scambia il contenuto delle variabili e lo stampa sullo schermo.
N.B.: Senza utilizzare nessuna variabile di appoggio!
Linguaggio C++


Con la variabili di appoggio non ho avuto nessun problema, ma adesso che non dobbiamo più usarla mi esce l'errore che manca input... allora il mio file sorgente è questo:

#include
using namespace std;
main ()
{
int i, j;
cout<<"inserisci il valore di i";
cin>>i;
cout<<"inserisci il valore di j";
cin>>j;

i=j;
j=i;

cout<<"Dopo lo scambio:i="< return 0;
}


Credevo di averlo risolto, ma invece il problema è che dopo lo scambio il valore delle due variabili è lo stesso i=j: credo quindi che sia un problema di definizione... Come fareste voi senza usare l'appoggio per scambiare le variabili (solo tipo int per ora)?

Grazie... e scusate le tante modifiche!!!!

Risposte
claudio862
In un programma reale la risposta corretta è usare la funzione offerta dalla libreria standard std::swap():

#include <algorithm>

...

int a = 3;
int b = 8;

std::swap(a, b);

// Ora a == 8, b == 3


Però immagino che questo esercizio sia volto a familiarizzare con le variabili, quindi dovrai scrivere tu l'equivalente di una funzione swap*.

La tua soluzione non funziona perché una volta che assegni ad i il valore di j, il valore originale di i non è più accessibile. Devi fare in modo da memorizzare entrambi i valori di i, j dentro un'unica variabile, e devi poter riottenerli entrambi.

Il metodo più famoso utilizza l'operatore logico "o esclusivo", simbolo ^:

if (a != b) {
    a = a ^ b;
    b = b ^ a;
    a = a ^ b;
}

Nota che non funziona se a == b (ma a quel punto non devi già fare niente, non ha senso scambiare due valori uguali).

Una variante, che forse è un po' più intuitiva, è usare somma e sottrazione:

unsigned int a = 3;
unsigned int b = 8;

a = a + b;   // Ora a == 3 + 8
b = a - b;   // Ora b == a - 8 == (3 + 8) - 8 == 3
a = a - b;   // Ora a == a - b == (3 + 8) - 3 == 8

             // a == 8, b == 3

Nota che questo metodo funziona solo per tipi unsigned, perché una delle somme potrebbe sforare il massimo (o minimo) valore possibile (overflow/underflow). In quel caso i tipi unsigned lavorano in aritmetica modulare e il risultato è corretto, mentre per i tipi signed un overflow/underflow ha risultato indefinito.


* Ma in un programma reale usa sempre std::swap()! È più chiara, e per alcuni tipi di dati complessi è molto più veloce di scambiare i valori esplicitamente. Per la cronaca std::swap() usa una variabile d'appoggio (anche se nell'ultima versione del C++ è di un tipo particolare che la rende più rapida anche in molti altri casi, ma questo è un argomento abbastanza avanzato).

vict85
Sinceramente lo trovo un esercizio di utilità limitata, persino la versione con gli or alle volte è più lenta della versione con la variabile di appoggio (per una descrizione più accurata si veda su wiki http://en.wikipedia.org/wiki/XOR_swap_algorithm). La maggior ragione per non farlo è che i compilatori sanno bene come ottimizzare un codice standard come uno scambio con una variabile temporanea costante e che alcune architetture possiedono un'istruzione per lo scambio, a quel punto richiamare quella istruzione, nel caso degli interi, ha molto più senso che usare lo scambio con gli or.

jorja92
Grazie Claudio86: alla fine ho ricontrollato tutto e ci sono riuscita. Grazie infiinete!

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.