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

Asked

Viewed 21,946 times

8

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

Ruby allows us to exchange the value between two variables easily and without using an auxiliary variable, thus:

a, b = b, a

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

  • 2

    possible duplicate of How to exchange the value of two variables in Java? Except the language, the practice is the same.

  • 2

    @Felipeavelar I don’t think the same question. The given question uses an intermediate variable to swap. And your answer with XOR given in the given question only applies to numbers.

  • 3

    Why? The use of auxiliary variable is the method recognized by 100% of C programmers to exchange the value between two variables. Also, most likely, the executable will be optimized and will not use auxiliary variable.

  • I agree with @Felipeavelar

  • 4

    I don’t agree with the closure, Java and C are two different languages, and there is room for specific responses to each, see the extended example that uses macros.

  • 1

    I don’t think it’s a duplicate of this java post, because told by @Bacco, my question is if in C it would be possible to do something similar exemplified in RUBY, without the use of auxiliary variable. They look alike, but they’re not the same.

  • @Bacco, but it is explained that it is not possible to swap in java, precisely because it does not accept passage by reference, which does not happen in C...

  • 2

    @Felipeavelar ie, is not duplicate even :)

Show 3 more comments

3 answers

12

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

Assuming 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 it helped.

  • 3

    And what happens if x = INT_MAX and y = INT_MAX?

  • Of course it’s an unorthodox method, but it’s the simplest because he doesn’t want a third variable.. But a "Convert.Toint32" or something like that could help

  • 1

    What I mean is not the type, but the fact that using the proposed solution, if x and y are INT_MAX, will cause an int overflow, causing Undefined behaviour.

  • I know, and you’re absolutely right, but I suppose that’s not the case or he wouldn’t be asking for this solution because the use of a third variable is the right one at any time. If it’s integers or something like that, the solution is correct otherwise I’m not seeing solution without using a 3rd. Cumpz

  • 1

    Correct, but in this case I think it is preferable to indicate in the response the limitations of the code, namely the possibility of overflows et al.

9


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

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

There is no limitation regarding the magnitude of the value. Yes, it works with INT_MAX. Try picking a number pair and doing this calculation by hand to understand how it works.

If you want to implement a macro that works for any type, we have some possibilities. The simplest way is the following:

#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 the GCC, the 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 failing silently.

Note that if you use the macro option, technically you will never really see the additional variable. So it’s as if it doesn’t exist, an abstraction.

To make a bolder version I took as a basis one made by @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 Highlight’s is wrong there. Ignore this.

The first step is to declare a variable whose name is temp##x##y. That contacts 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 build 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 (it is a huge struct), memcpy is the fastest way to do it anyway. Note that typeof is not used.

-3

a = (a * b);
b = a / b;
a = a /b ;

Browser other questions tagged

You are not signed in. Login or sign up in order to post.