Vediamo un semplice esempio di c per scambiare due numeri senza usare la terza variabile.
programma 1:
#include<stdio.h>
#include<conio.h>
main()
{
int a=10, b=20;
clrscr();
printf("Before swap a=%d b=%d",a,b);
a=a+b;//a=30 (10+20)
b=a-b;//b=10 (30-20)
a=a-b;//a=20 (30-10)
printf("\nAfter swap a=%d b=%d",a,b);
getch();
}
Produzione:
Prima dello scambio a = 10 b = 20 Dopo lo scambio a = 20 b = 10
Programma 2: utilizzo di * e /
Vediamo un altro esempio per scambiare due numeri usando * e /.
#include<stdio.h>
#include<conio.h>
main()
{
int a=10, b=20;
clrscr();
printf("Before swap a=%d b=%d",a,b);
a=a*b;//a=200 (10*20)
b=a/b;//b=10 (200/20)
a=a/b;//a=20 (200/10)
printf("\nAfter swap a=%d b=%d",a,b);
getch();
}
Produzione:
Prima dello scambio a = 10 b = 20 Dopo lo scambio a = 20 b = 10
Programma 3: utilizzo dell'operatore XOR bit per bit:
L'operatore XOR bit per bit può essere utilizzato per scambiare due variabili. Lo XOR di due numeri xey restituisce un numero che ha tutti i bit come 1 ogni volta che i bit di xey differiscono. Ad esempio, XOR di 10 (in binario 1010) e 5 (in binario 0101) è 1111 e XOR di 7 (0111) e 5 (0101) è (0010).
#include <stdio.h>
int main()
{
int x = 10, y = 5;
// Code to swap 'x' (1010) and 'y' (0101)
x = x ^ y; // x now becomes 15 (1111)
y = x ^ y; // y becomes 10 (1010)
x = x ^ y; // x becomes 5 (0101)
printf("After Swapping: x = %d, y = %d", x, y);
return 0;
Produzione:
Dopo lo scambio: x = 5, y = 10
Programma 4:
Nessuno ha ancora suggerito di usare std :: swap.
std::swap(a, b);
Non uso variabili temporanee e, a seconda del tipo di aeb, l'implementazione potrebbe avere una specializzazione che non ne ha neanche uno. L'implementazione dovrebbe essere scritta sapendo se un "trucco" è appropriato o meno.
Problemi con i metodi sopra:
1) L'approccio basato sulla moltiplicazione e sulla divisione non funziona se uno dei numeri è 0 poiché il prodotto diventa 0 indipendentemente dall'altro numero.
2) Entrambe le soluzioni aritmetiche possono causare un overflow aritmetico. Se xey sono troppo grandi, l'addizione e la moltiplicazione potrebbero non rientrare nell'intervallo di numeri interi.
3) Quando usiamo puntatori a una variabile e facciamo uno scambio di funzione, tutti i metodi precedenti falliscono quando entrambi i puntatori puntano alla stessa variabile. Diamo un'occhiata a cosa succederà in questo caso se entrambi puntano alla stessa variabile.
// Metodo basato su XOR bit per bit
x = x ^ x; // x becomes 0
x = x ^ x; // x remains 0
x = x ^ x; // x remains 0
// Metodo basato su aritmetica
x = x + x; // x becomes 2x
x = x – x; // x becomes 0
x = x – x; // x remains 0
Vediamo il seguente programma.
#include <stdio.h>
void swap(int *xp, int *yp)
{
*xp = *xp ^ *yp;
*yp = *xp ^ *yp;
*xp = *xp ^ *yp;
}
int main()
{
int x = 10;
swap(&x, &x);
printf("After swap(&x, &x): x = %d", x);
return 0;
}
Uscita :
Dopo lo scambio (& x, & x): x = 0
Lo scambio di una variabile con se stessa può essere necessario in molti algoritmi standard. Ad esempio, guarda questa implementazione di QuickSort dove possiamo scambiare una variabile con se stessa. Il problema di cui sopra può essere evitato ponendo una condizione prima dello scambio.
#include <stdio.h>
void swap(int *xp, int *yp)
{
if (xp == yp) // Check if the two addresses are same
return;
*xp = *xp + *yp;
*yp = *xp - *yp;
*xp = *xp - *yp;
}
int main()
{
int x = 10;
swap(&x, &x);
printf("After swap(&x, &x): x = %d", x);
return 0;
}
Uscita :
Dopo lo scambio (& x, & x): x = 10