0

I want to swap two variables using pointers without any function call or any temp variable.

My current code is:

void main()
{
  int a=1, b=2, *c;

  cout << a << b << endl;

  *c = a;
  a = b;
  b = *c;

  cout << a << b << endl;

  getch();
}

The code works on Turbo C++ but not on Visual Studio, plus I read it was bad practice to have an uninitialized pointer variable.

So can anyone tell me what changes I need to make in this code for it to work on visual studio? If there is a better way please tell.

Thanks..

Rook
  • 5,734
  • 3
  • 34
  • 43
Waqas Ali
  • 19
  • 1
  • 7
  • 4
    **Why** do you want to use a pointer variable but not a temporary `int` variable? –  May 20 '14 at 17:29
  • 1
    Essentially using `*c` is the same like `int c; c = ...`. Just with indirection. – dornhege May 20 '14 at 17:30
  • I want to discover all the ways I can swap two variables. 1. Third Variable 2. XOR Algo 3. Pointers using functions what else? – Waqas Ali May 20 '14 at 17:30
  • 3
    There's really only two ways. A third variable, and XOR. All other algorithms are going to be complicated ways to hide the fact there's a third variable. – Mooing Duck May 20 '14 at 17:38
  • When you say without using "any temp variable", do you mean you don't want a temporary variable to appear in *your* code? Or do you mean you don't want the compiled code that actually executes to use a temporary variable? – David Schwartz May 20 '14 at 17:38
  • 1
    With the constraints you have imposed on yourself, the answer is that you can't do it reliably. – R Sahu May 20 '14 at 17:43
  • It's not valid to dereference a pointer without initializing it. If that's part of your set of conditions, then you can't do it and the question becomes basically pointless. – Michael Burr May 20 '14 at 17:55
  • That code is undefined due to the uninitialised pointer, but for small enough values, like 1 and 2, you can use the high bits of one of the variables as swap space. (wink-smiley) – molbdnilo May 20 '14 at 17:58

3 Answers3

2

You can't use c's value until you set some value. So *c = a; is nonsense. You have to do c = <something> first.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278
  • Yeah I know its illegal But it worked on Turbo C++ – Waqas Ali May 20 '14 at 17:26
  • 2
    @WaqasAli Yes, but that's why it didn't work *reliably*. You asked why it didn't work reliably and how to fix it, and that's what I told you. Set it to a correct value and it will work reliably. – David Schwartz May 20 '14 at 17:27
  • So you're asking me to assign some address to pointer c but for that I would be initializing another variable, effectively ending my purpose – Waqas Ali May 20 '14 at 17:32
  • Honestly, I have no idea how to respond to that. You can shoot blind and miss most of the time or you can aim. If you don't want to aim, then you're going to miss a lot. (You're not achieving your purpose anyway. Turbo C++ optimizes your code by using a temporary register variable and ignoring your pointer.) – David Schwartz May 20 '14 at 17:36
0

You can use the so-called XOR swap, see this link http://en.wikipedia.org/wiki/XOR_swap_algorithm

if(&a != &b) // test that the 2 variables don't have the same address (in this case you get a=b=0)
{
   a = a^b;
   b = a^b;
   a = a^b;
}

Using pointers (from Wikipedia)

 void xorSwap (int *x, int *y)
 {
     if (x != y)
     {
         *x ^= *y;
         *y ^= *x;
         *x ^= *y;
     }
 }

There are other ways of doing this without a temp, like the addition/subtraction method

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

but you should always rely on the compiler to do the optimization for you, i.e. use a temp and don't worry about it.

vsoftco
  • 55,410
  • 12
  • 139
  • 252
  • I want to do it using pointers – Waqas Ali May 20 '14 at 17:27
  • Good answer, but you should spell it out and not rely on a link. – Beta May 20 '14 at 17:27
  • The addition/subtraction method [is broken](http://stackoverflow.com/q/13317684/395760) when written like that. I don't see a way to ; one can use it in languages with stricter rules regarding side effect timing but in any case you're relying on creating temporary variables *implicitly* (to hold the result of either `a=b` or the first `a`, whichever comes first). –  May 20 '14 at 17:45
  • @delnan ok, thanks, I was not sure about the order of evaluation in `expr1 + expr2`, changed the code accordingly – vsoftco May 20 '14 at 17:51
  • Yeah, that should work. Except for overflow of course. But this is such a contrived problem that I feel silly pointing out its problems. –  May 20 '14 at 17:52
  • Yes, sure, I would just completely avoid this kind of "optimizations" :) – vsoftco May 20 '14 at 17:53
0

Here are some platform specific methods in psuedo-assembly language:

Push & Pop
Many processors have instructions to push a value onto the stack and load it.
This is essentially the same method as using a temporary variable.

push register 0
push register 1
pop register 0
pop register 1

Exchange instruction
Some processors have an exchange (e.g. xchg) which allows you to exchange (swap) two registers. Some processors may allow you to exchange a register with a memory location.
xchg R0, R1 ; Exchange register 0 with register 1.

Summary
Some processors have the capability of pushing onto a stack and popping from a stack. This could be used to swap values in registers. Another processor dependent method for swapping is to use a processor "exchange" or "swap" instruction. Not all processor have these instructions, so these techniques are not portable.

Thomas Matthews
  • 56,849
  • 17
  • 98
  • 154