When would you swap two numbers without using a third variable?
At this point it's just a neat trick. Speed-wise if it makes sense though your compiler will recognize a normal swap and optimize it appropriately (but no guarantees that it will recognize weird xor
ing and optimize that appropriately).
Swapping two variable value without using third variable
Using the xor swap algorithm
void xorSwap (int* x, int* y) {
if (x != y) { //ensure that memory locations are different
*x ^= *y;
*y ^= *x;
*x ^= *y;
}
}
Why the test?
The test is to ensure that x and y have different memory locations (rather than different values). This is because (p xor p) = 0
and if both x and y share the same memory location, when one is set to 0, both are set to 0.
When both *x and *y are 0, all other xor operations on *x and *y will equal 0 (as they are the same), which means that the function will set both *x and *y set to 0.
If they have the same values but not the same memory location, everything works as expected
*x = 0011
*y = 0011
//Note, x and y do not share an address. x != y
*x = *x xor *y //*x = 0011 xor 0011
//So *x is 0000
*y = *x xor *y //*y = 0000 xor 0011
//So *y is 0011
*x = *x xor *y //*x = 0000 xor 0011
//So *x is 0011
Should this be used?
In general cases, no. The compiler will optimize away the temporary variable and given that swapping is a common procedure it should output the optimum machine code for your platform.
Take for example this quick test program written in C.
#include <stdlib.h>
#include <math.h>
#define USE_XOR
void xorSwap(int* x, int *y){
if ( x != y ){
*x ^= *y;
*y ^= *x;
*x ^= *y;
}
}
void tempSwap(int* x, int* y){
int t;
t = *y;
*y = *x;
*x = t;
}
int main(int argc, char* argv[]){
int x = 4;
int y = 5;
int z = pow(2,28);
while ( z-- ){
# ifdef USE_XOR
xorSwap(&x,&y);
# else
tempSwap(&x, &y);
# endif
}
return x + y;
}
Compiled using:
gcc -Os main.c -o swap
The xor version takes
real 0m2.068s
user 0m2.048s
sys 0m0.000s
Where as the version with the temporary variable takes:
real 0m0.543s
user 0m0.540s
sys 0m0.000s
Swapping the values of two variables without using third variable in C?
This algorithm does not work because it invokes undefined behavior on this line:
x=x+y-(y=x);
^ ^
You are modifying y
and also using its value within the same sequence point as per section 6.5
of the draft C99 standard:
Between the previous and next sequence point an object shall have its
stored value modified at most once by the evaluation of an
expression.72) Furthermore, the prior value shall be read only to
determine the value to be stored.73)
There is also the matter of unspecified behavior since the order of evaluation of the sub-expressions is unspecified:
The grouping of operators and operands is indicated by the syntax.74)
Except as specified later (for the function-call (), &&, ||, ?:, and
comma operators), the order of evaluation of subexpressions and the
order in which side effects take place are both unspecified.
In this case if you were using clang
it would have provided the following warning:
warning: unsequenced modification and access to 'y' [-Wunsequenced]
x=x+y-(y=x);
~ ^
as far as I can tell by default. You can receive a similar warning from gcc
by using -Wall
.
There are several SO questions that cover how to swap without a temporary for example Swapping two variable value without using 3rd variable.
R: Swap two variables without using a third
For integers, you can use
a = a + b
b = a - b
a = a - b
and for strings, this would work
a <- "one"
b <- "two"
a <- paste(a,b, sep = "")
b <- substr(a,0,nchar(a) - nchar(b))
a <- substr(a,nchar(b) + 1, nchar(a))
> a
# two
> b
# one
Why Swapping without third variable not working here?
Your values of h
and i
are not quaranteed to be different.
Swapping in this case will not only not swap anything but also mess up your memory.
void selectsort(int*p ,int q){
int i,j,h,temp;
for(i=0;i<q-1;i++){
h=i; // <=== Here you start with identical values
for(j=i+1;j<q;j++){
if(p[h]>p[j]){
h=j; // This may or may not be executed.
}
}
// Here h can still be at same value as i.
// What happens in this case is shown in the comments below:
p[i]=p[i]+p[h]; // p[i]=p[i]+p[i]; ==> p[i] *=2;
p[h]=p[i]-p[h]; // p[i]=p[i]-p[i]; ==> p[i] = 0;
p[i]=p[i]-p[h]; // p[i]=p[i]-p[h]; ==> p[i] = 0;
}
}
You could add something like this before doing the swapping:
if (i==h)
continue;
Note:
Apart from academic cases I would not suggest using such an approach.
Swapping without a temporary variable has lots of downsides:
- Only works for integer types
- Needs handling for overflow etc.
- Needs handling for identical storage locations.
- Needs extra arithmetic operations causing more code and longer execution time
- Is confusing readers and harder to maintain
It also only has one advantage
- Saves stack storage for 1 variable.
If your goal is to confuse readers, then you should search for a version using XOR instead of arithmetics. ;)
Swapping values of two variables without using a third one- Array
You can store them in an array (like you were trying to in some of the commented code), and then swap them one by one.
#include <stdio.h>
int main()
{
int x, y, p, i;
printf ("How many pairs?\n");
scanf ("%d", &p);
int a[p],b[p];
for(i=0; i<p; i++)
{
printf ("Enter values for pair %d:\n", i+1);
scanf("%d %d",&a[i],&b[i]);
}
for(i=0; i<p; i++)
{
x = a[i];
y=b[i];
x = x + y;
y = x - y;
x = x - y;
printf("Pair %d After Swapping: x = %d, y = %d\n", i+1, x, y);
}
return 0;
}
Try it here: http://goo.gl/5JJ7i3
Related Topics
C++ Logon Task Schedule Error: No Mapping Between Account Names and Security Ids Was Done
Quadruple Precision in C++ (Gcc)
Why Class Size Depend Only on Data Members and Not on Member Functions
How to Implement "_Mm_Storeu_Epi64" Without Aliasing Problems
How to Write Make_Unique() in VS2012
C++ Template Function Default Value
Cmake Imported Library Behaviour
C++ Initializing Non-Static Member Array
Does the Unary + Operator Have Any Practical Use
Concurrent Writes in the Same Global Memory Location
Understanding Rvalue References