How to change the value between two variables without using an auxiliary variable?

7

I learned to program in C, but recently I have studied RUBY.

Ruby allows you to change the value between two variables easily and without using an auxiliary variable, like this:

a, b = b, a

Without using an auxiliary variable, how can I do this in C?

    
asked by anonymous 20.05.2014 / 05:15

3 answers

6

If you are only using integer types ( int , long , unsigned char , ...) you can use a trick with XOR, like this:

x ^= y;
y ^= x;
x ^= y;

There is no limitation to the magnitude of the value. Yes, it works with INT_MAX . Try to pick a pair of numbers and make that calculation on hand to understand how it works.

If you want to implement a macro that works for any type, we have some possibilities. The simplest form is as follows:

#define SWAP(x, y) do {   \
      typeof(x) temp = x; \
      x = y;              \
      t = temp;           \
    } while (0)

This works for the general case, but has some problems. First, it depends on an extension of GCC, typeof . This is not present in all compilers. Second you can pass different types to x and y, and this should not be allowed. And finally, if one of the variables is called temp , you will have the macro crashing silently.

Note that if you use the macro option, technically you will never actually see the additional variable. So it is as if it did not exist, an abstraction.

To make a more bold version, I took one based on @adamk :

#define SWAP(x, y) do { \ 
      unsigned char temp##x##y[sizeof(x) == sizeof(y) ? sizeof(x) : -1]; \
      memcpy(temp##x##y, &y, sizeof(x)); \
      memcpy(&y, &x,         sizeof(x)); \
      memcpy(&x, temp##x##y, sizeof(x)); \
    } while(0)

Unfortunately the highlight is wrong there. Ignore this.

The first step is to declare a variable whose name is temp##x##y . This counts on temp , x and y , ensuring that the identifier is never equal to either. Then an array is declared with sizeof(x) bytes. But note that if sizeof(x) != sizeof(y) , the size will be -1 and the compilation will fail. Finally the copy is done using memcpy . It may seem inefficient but in reality it is not. If the size is small the compiler will remove this and make the copy directly. If the size is large (for a huge struct), memcpy is the quickest way to do this anyway. Note that typeof is not used.

    
20.05.2014 / 12:16
7

One of the simplest and quickest ways to do this is to use mathematical operations.

Assuming that x = 50 and y = 70 with 3 operations:

x= x + y 
y= x - y 
x= x - y

Detailed explanation

• x= x + y | x= 70 + 50 , basicamente x=120

• y= x - y | y = 120 - 70 , ficamos com y=50

• x= x - y | x= 120 - 50 , finalmente x=70.

I hope you have helped.

    
20.05.2014 / 11:19
-5
a = (a * b);
b = a / b;
a = a /b ;
    
20.03.2016 / 23:23