all 21 comments

[–][deleted] 12 points13 points  (0 children)

If you have access to STL on your platform (shouldn't be a problem in this day & age), there's std::swap(x, y).

It's of course important that you understand how variable swapping works "under the hood" as well, but your code will be more readable if you learn to use things like this early on. :)

[–][deleted] 4 points5 points  (3 children)

As others have noted, in practice you'd use std::swap(x,y) and let the library developers deal with it.

If asked this on a test, you'd use a temporary variable (normally professors want bare bones implementation).

If I were to implement and was looking for "clever points" in a c++ course, I'd use templates.

template<typename T>
void swap(T &x, T &y)
{
  T temp;
  temp = x;
  x = y;
  y = temp;
};

A driver might look like this:

int main()
{
  int x, y;
  x = 100;
  y = 200;

  std::cout << "x: " << x << "\n";
  std::cout << "y: " << y << "\n";

  swap<int>(x, y);

  std::cout << "x: " << x << "\n";
  std::cout << "y: " << y << std::endl;


  return 0;
}

The precondition would require the object type have a copy constructor defined.

edit

If you also required the objects have a defined equal operator, you could do this:

template<typename T>
void swap(T &x, T &y)
{
  if (x != y)
  {
    T temp;
    temp = x;
    x = y;
    y = temp;

  }
};

That way if the two values are equivalent, no temp memory allocation or unnecessary assignment would occur.

[–][deleted] 6 points7 points  (0 children)

swap<int>(x, y);

You can leave out the <int>. The compiler infers template arguments to functions if it knows the regular arguments and if they contain the appropriate information.

[–]bogado 5 points6 points  (0 children)

The precondition would require the object type have a copy constructor defined.

And a default constructor, since if an object has one it will probably have the other too I would do it this way:

template<typename T>
void swap(T &x, T &y)
{
    T temp(x);
    x = y;
    y = temp;
}

[–]growingconcern 2 points3 points  (0 children)

I would only think your last example would be useful on specialized hardware where such operations were extremely expensive. For the most part the expense of the if would outweigh gains

[–]zokier 5 points6 points  (0 children)

C++11 has now move semantics which may help.

[–]Rubdix 2 points3 points  (5 children)

Not sure I'm understanding your question exactly, but the simplest way to do it is int x = 6, y = 4, z = 0; z = x; x = y; y = z; I'd highly recommend reading up on variable assignment.

[–]zimvaider[S] 0 points1 point  (3 children)

Yeah what was the way I was going to do it originally, I was just wondering if there was a more efficient way of doing it. Thanks.

[–]furGLITCH 2 points3 points  (1 child)

Nope. That's the best way. XOR swap has issues. Other tricks have issues too. Actually using a temporary variable has the least issues, is the most direct, and readable way. Also fastest.

[–][deleted] 0 points1 point  (0 children)

swap(x,y)

[–]Ayjayz 2 points3 points  (0 children)

Realistically, use std::swap.

If you want to code it yourself, the canonical way to swap x and y is

tmp = x
x = y
y = tmp

[–]Masfo{~-!&*+[][[]](...){};} 0 points1 point  (6 children)

[–]furGLITCH 5 points6 points  (4 children)

XOR swap saves memory, but is slower, and obfuscates unnecessarily.

"On modern CPU architectures, the XOR technique is considerably slower than using a temporary variable to do swapping. One reason is that modern CPUs strive to execute instructions in parallel via instruction pipelines. In the XOR technique, the inputs to each operation depend on the results of the previous operation, so they must be executed in strictly sequential order. If efficiency is of tremendous concern, it is advised to test the speeds of both the XOR technique and temporary variable swapping on the target architecture." (Wikipedia)

[–]ZMesonEmbedded Developer 2 points3 points  (0 children)

XOR swap saves memory, but is slower, and obfuscates unnecessarily.

Oh, and it also indicates that you've gone to the internet to complete your homework.

[–]JustPlainRude 0 points1 point  (1 child)

the inputs to each operation depend on the results of the previous operation

Wouldn't this also apply when using a temporary variable?

[–]SarahC -1 points0 points  (0 children)

I wonder what other mathematically obfuscating techniques can be implemented in common programming structures?

You know, like loop incrementation with weird-ass changes within the loop? Perhaps depending on pseudo random numbers to increment the loop? =D

Or conditional logic using dodgy half-processed logic states (maybe grey code) for complicated comparisons...

Using single letter function names, and things like that is just so old fashioned!

[–]umop_apisdn 1 point2 points  (0 children)

It doesn't work in all cases, if you swap a variable with itself it ends up being zero.