all! Could someone please help me to solve such a task. I need to swap variable values without using any assignment signs. I tried to do it with a while loop but I coudn't store counter value anywhere. Thank you all in advance.
-
3I've tagged this as homework for you -- I can't think of any other origin of this strange 'need' that you have. – High Performance Mark Oct 12 '10 at 09:11
-
Does this count? http://stackoverflow.com/questions/249423/how-does-xor-variable-swapping-work – Greg Hewgill Oct 12 '10 at 09:11
-
2@0xA3 - If it's actually for concurrency, it doesn't matter whether it looks like `=` or is only `=` under the hood--you'll still have problems. What you want is "How do I swap two variables atomically". And the answer for that is different than, "How do I update a variable while obtaining its previous value atomically"? – Rex Kerr Oct 12 '10 at 18:51
8 Answers
You can use Interlocked.Exchange
.

- 172,527
- 53
- 255
- 316
-
Could someone show how ? why doesn't this works : Interlocked.Exchange(ref b, Interlocked.Exchange(ref a, b)); – hoang Oct 12 '10 at 11:12
-
1So shifting the problem to a library routine whose implementation we can't see counts as a solution? Without even showing how to use the library routine to accomplish the stated goal? – LarsH Oct 12 '10 at 22:08
-
Maybe you're not showing how to use Interlocked.Exchange to accomplish this because it might be a homework assignment. I'm curious too, though, if @hoang's example doesn't work. – LarsH Oct 12 '10 at 22:14
-
@hoang: Your sample should work. What types are `a` and `b`? Do you get an exception or compiler error? – Dirk Vollmar Oct 12 '10 at 22:52
-
@LarsH: See the Hans Passant's answer about the implementation of `Interlocked.Exchange` here: http://stackoverflow.com/questions/3855671/how-do-i-atomically-swap-2-ints-in-c/3855824#3855824 – Dirk Vollmar Oct 12 '10 at 22:53
-
@OxA3: It works but i wrapped the call inside a method and forgot to put the ref parameters : the following compile but doesn't work : private void InterlockedSwap(int a, int b) { Interlocked.Exchange(ref b, Interlocked.Exchange(ref a, b)); } – hoang Oct 13 '10 at 08:07
-
while this works : private void InterlockedSwap(ref int a, ref int b) { Interlocked.Exchange(ref b, Interlocked.Exchange(ref a, b)); } – hoang Oct 13 '10 at 08:08
-
@0xA3: thanks for the answers. So maybe the general solution to the question is "use a library routine that's not written in C# so it doesn't need to use assignment". – LarsH Oct 13 '10 at 11:20
Since integers are immutable in C#, you cannot "Swap Integer variables without using any assignment"; you will need to reassign them somewhere, somehow. Perhaps you mean Swap two variables without using a temp variable?
Or, if you meant without explictly using =
, @Konrad Rudolph's answer is the way to go.
Xor-swap uses assignments. But perhaps you’re allowed to use increment and decrement (which, strictly speaking, resolve to += 1
and -= 1
in C# but logically they are often considered to be different).
int tmp = 0; // C# complains if we don’t initialize!
while (a-- > 0)
tmp++;
while (b-- > 0)
a++;
while (tmp-- > 0)
b++;
This is a logic sometimes used in the analysis of primitive calculi, such as the LOOP program formalism. Of course, these formalisms don’t require initialization of fields, otherwise the whole “no assignment” rule would be completely moot. In a strict calculus, tmp
would have to be zero-initialized by a loop, too:
while (tmp > 0)
tmp--;
This will work no matter what value tmp
had before (provided tmp > 0
, which is usually a requirement in all these calculi: negative numbers don’t exist).
But, to stress this once again, C# requires us to initialize each local variable (non-local variables are default-initialized) so this loop would be redundant in C#, and an initialization is still required.
As @Doc Brown pointed out in the comments, this only works for (positive!) integers – although theoretically (once again: not in C#!) this could be made to work with any type that can be represented on a Von Neumann architecture since they all reside in memory as numbers (to some base).

- 530,221
- 131
- 937
- 1,214
-
1
-
Kobi is right. Since that would violate the 'rules', I guess you could make it a field? – Ani Oct 12 '10 at 09:23
-
@Kobi, @Ani: You’re right. C# requires initialization, I forgot. See the updated text. I think this is as close as we can get (with local variables). – Konrad Rudolph Oct 12 '10 at 09:23
-
-
-
1@Konrad: you should add a remark that this does only work for integers. – Doc Brown Oct 12 '10 at 09:29
-
1@Kobi: That actually came as a surprise. How can I not have noticed that before?! :) – Jakob Oct 12 '10 at 09:29
-
class Program
{
private static void Swap(ref int a, ref int b)
{
int.TryParse((a ^ b).ToString(), out a);
int.TryParse((a ^ b).ToString(), out b);
int.TryParse((a ^ b).ToString(), out a);
}
static void Main(string[] args)
{
int a = 42;
int b = 123;
Console.WriteLine("a:{0}\nb:{1}", a, b);
Swap(ref a, ref b);
Console.WriteLine("a:{0}\nb:{1}", a, b);
}
}

- 1,887
- 1
- 24
- 34
See Bit Twiddling Hacks it'll show you how to do it in a number of different ways without using assignments.

- 6,905
- 2
- 32
- 35
-
These show ways to swap values without using a temporary variable, not without using assignment (unless you consider `op=` not to be an assignment). – LarsH Oct 12 '10 at 22:04
Does xor-swap count?
x ^= y;
y ^= x;
x ^= y;

- 24,154
- 8
- 46
- 57
-
@Ani: That's why I asked :) The whole issue boils down to what you consider as an assignment. Konrads answer is an even better illustration of that since whether or not ++/-- are assignments is even more fuzzy. – Jakob Oct 12 '10 at 09:23
I don't think this is even possible in C#.
The XOR answer is the standard, but you can only grab hold of the memory and manipulate its values directly in lower-level languages.
.net languages will allow you to perform the equivalent of an XOR operation and return the value but to store it you still have to assign it, as far as I'm aware. You just don't have the direct memory access to perform the operation in this manner, as far as I can think...

- 7,965
- 12
- 50
- 86