2
#include<stdio.h>

int main()
{

    int a=20,b=30;

    a=a+b;
    b=a-b;
    a=a-b;



    return 0;
}

Can I use this program to swap both positive and negative values.

Aziz Ahmed
  • 49
  • 6

5 Answers5

7

The algorithm for swapping variables without a temporary holder uses the bitwise XOR operation, not subtraction. So, using variables named a and b, we'd have:

a=a^b;
b=a^b;
a=a^b;

EDIT: Your code does work for the few cases I tested it with using some integral values for a and b, but XOR is the conventional way of doing it. As commenter @wildplasser pointed out, the reason XOR is the convention is that integer addition and subtraction can overflow, giving incorrect results, whereas XOR cannot.

Govind Parmar
  • 20,656
  • 7
  • 53
  • 85
  • 7
    The reason for this is that integer addition can overflow, and the behaviour at integer overflow is undefined. XOR cannot overflow – wildplasser Jun 03 '17 at 13:36
  • 1
    Your first sentence is incorrect. XOR swap is not the only way to swap without a temporary variable – phuclv Jun 03 '17 at 13:51
  • also, even case of overflow, when you add something with overflow and then substract the same thing, you get underflow and the same previous value (even against the hordes of defenders of the undefined behaviour thing) so, I'm afraid that theoretically, using `xor` or `+` and `-` is equivalent. Overflowing registers is some kind of modular arithmetic, well known since long ago, and for this case sum and exclusive or are equivalent operations. – Luis Colorado Jun 04 '17 at 08:37
  • 3
    @LuisColorado Signed integer overflow is *undefined* by the C standard. – Govind Parmar Jun 04 '17 at 11:15
4

This method will not work if a+b overflows as this invokes undefined behavior.

It's better to use the XOR method. Even better, use a temp anyway as it's more clear.

dbush
  • 205,898
  • 23
  • 218
  • 273
  • i'm not going to discuss this, but I'm afraid not. Even with overflow, there's no undefined behaviour in modular arithmetic (what is what happens in this case) Of course, you can get some implementation written ex-profeso to fail in this case, and it will be completely standard compliant. But, can you cite just one in which behaviour is different? We are getting to far with the U.B. feature... – Luis Colorado Jun 04 '17 at 08:39
  • And to Luis Colorado's point, by the same token, it's a perfectly fine idea to hold a gun to your head and pull the trigger, as long as you know the gun is not loaded. – Steve Summit Jun 05 '17 at 10:53
3

As others have pointed out, you should use XOR instead of arithmetic operators to avoid UB due to signed overflow.

But keep in mind that in most common processors (x86, ARM, 68k, etc.) 3 logical operations will be slower (and consume more energy) than 3 moves between registers. So, provided enough registers are available (which in your example is most surely the case) and optimization enabled, using a temporary will be faster than bit twiddling. Finally, some architectures have an exchange instruction (e.g. xchg on x86), a smart enough compiler should be able to use it, and that would be even faster.

The moral of the story - beware premature optimization.

rustyx
  • 80,671
  • 25
  • 200
  • 267
2

There is no preferred way to swap two variables without using a temporary variable in C.

The preferred way to swap two variables in C is to use a temporary variable.

Swapping without using a temporary is an obsolete problem. It might once have been an interesting problem back when we were writing (a) assembly language code for (b) machines with very few registers and not much memory. But when we're writing in a higher level language like C, on a machine with ample memory and registers, there is nothing -- nothing! -- positive to be gained by trying to eliminate the temporary variable.

Asking "What's the best way to swap two variables without using a temporary?" is a lot like asking "What's the best way to get my horse to pull my buggy without using a buggy whip?".

(Sorry for the opinionated answer, but while swapping without using temporaries might be an interesting intellectual problem, it is a an error-prone waste of time in any practical programming situation. The likelihood that you will improve the performance of your program by eliminating the temporary is zero. The likelihood that you will introduce subtle bugs is substantially nonzero.)

Steve Summit
  • 45,437
  • 7
  • 70
  • 103
1

Yep it can be used for both positive and negative values but the problem with this method is when the numbers are large a+b can go out of the range and that can lead to a strange behaviour. Using temp variable for swapping is a good and simple way so use that whenever possible.

Nadeem
  • 121
  • 2
  • 13
  • there's no strange behaviour on large numbers... overflow happens and then happens back again. He is adding some number and sbstracting back the other number around `0`. overflow arithmetic is modular arithmetic (signed arithmetic is also modular, with an offset) and, for this case, it's the same. – Luis Colorado Jun 04 '17 at 08:43
  • 3
    @LuisColorado You are incorrect. Overflow arithmetic is guaranteed to be modular only for unsigned integers. For signed integers, it might be (and indeed it is on many popular machines), but this is not guaranteed by the C Standard. – Steve Summit Jun 04 '17 at 12:28
  • @SteveSummit, I'm not incorrect. I expected this answer. Can you tell me just **one** implementation that does not implement as said? It's incorrect from the standard perspective, but no implementation does this. 99.9999% of implementations use two's complement for signed and modulo 2^n for the unsigned ones. I know your asseveration, believe me, but after 40+ years programming in C, I haven't seen any such actual implementation (probably a C language compiler for Dr. Knuth's MIX virtual machine being the most notable possibility, as this machine doesn't use two's complement internally) – Luis Colorado Jun 05 '17 at 04:39
  • @LuisColorado When there's a compelling reason to do X, but where X is questionably valid, the question "On how many platforms does X *actually* not work?" can be appropriate. But here, it's doubly pointless: swapping two variables without using a temporary is basically a stupid idea to begin with, and even if you're bound and determined to do it, the "portable" solution using XOR is always available. – Steve Summit Jun 05 '17 at 10:48
  • @SteveSummit, just to finalize, I use to be pragmatic, so I always use the temp storage solution. Even the xor approach demonstrates to be useless today in the majority of platforms. But the question was not about the most pragmatic solution, but about the possibility of doing in one _well, strange_ way. – Luis Colorado Jun 05 '17 at 18:20