Vamos ver um exemplo simples de c para trocar dois números sem usar a terceira variável.
programa 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();
}
Resultado:
Antes da troca a = 10 b = 20 Após a troca a = 20 b = 10
Programa 2: Usando * e /
Vamos ver outro exemplo para trocar dois números 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();
}
Resultado:
Antes da troca a = 10 b = 20 Após a troca a = 20 b = 10
Programa 3: Fazendo uso do operador XOR bit a bit:
O operador XOR bit a bit pode ser usado para trocar duas variáveis. O XOR de dois números x e y retorna um número que tem todos os bits como 1 sempre que os bits de x e y diferem. Por exemplo, XOR de 10 (In Binary 1010) e 5 (In Binary 0101) é 1111 e XOR de 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;
Resultado:
Após a troca: x = 5, y = 10
Programa 4:
Ninguém sugeriu usar std :: swap, ainda.
std::swap(a, b);
Eu não uso nenhuma variável temporária e dependendo do tipo de aeb, a implementação pode ter uma especialização que também não. A implementação deve ser escrita sabendo se um 'truque' é apropriado ou não.
Problemas com os métodos acima:
1) A abordagem baseada na multiplicação e divisão não funciona se um dos números for 0, já que o produto se torna 0 independentemente do outro número.
2) Ambas as soluções aritméticas podem causar estouro aritmético. Se x e y forem muito grandes, a adição e a multiplicação podem sair do intervalo inteiro.
3) Quando usamos ponteiros para uma variável e fazemos uma troca de função, todos os métodos acima falham quando ambos os ponteiros apontam para a mesma variável. Vamos dar uma olhada no que acontecerá neste caso se ambos estiverem apontando para a mesma variável.
// Método baseado em XOR bit a bit
x = x ^ x; // x becomes 0
x = x ^ x; // x remains 0
x = x ^ x; // x remains 0
// Método baseado em aritmética
x = x + x; // x becomes 2x
x = x – x; // x becomes 0
x = x – x; // x remains 0
Vamos ver o seguinte programa.
#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;
}
Resultado :
Após a troca (& x, & x): x = 0
A troca de uma variável com ela mesma pode ser necessária em muitos algoritmos padrão. Por exemplo, veja esta implementação do QuickSort onde podemos trocar uma variável com ele mesmo. O problema acima pode ser evitado colocando uma condição antes da troca.
#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;
}
Produto :
Após a troca (& x, & x): x = 10