1

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.

3
  • 3
    I've tagged this as homework for you -- I can't think of any other origin of this strange 'need' that you have. Commented Oct 12, 2010 at 9:11
  • Does this count? stackoverflow.com/questions/249423/… Commented Oct 12, 2010 at 9: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"? Commented Oct 12, 2010 at 18:51

8 Answers 8

7

You can use Interlocked.Exchange.

Sign up to request clarification or add additional context in comments.

8 Comments

Could someone show how ? why doesn't this works : Interlocked.Exchange(ref b, Interlocked.Exchange(ref a, b));
So 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?
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.
@hoang: Your sample should work. What types are a and b? Do you get an exception or compiler error?
@LarsH: See the Hans Passant's answer about the implementation of Interlocked.Exchange here: stackoverflow.com/questions/3855671/…
|
6

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.

Comments

6

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).

8 Comments

Souldn't you initialize tmp to 0?
Kobi is right. Since that would violate the 'rules', I guess you could make it a field?
@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: you should add a remark that this does only work for integers.
@Kobi: That actually came as a surprise. How can I not have noticed that before?! :)
|
4
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);
    }
}

Comments

2

See Bit Twiddling Hacks it'll show you how to do it in a number of different ways without using assignments.

1 Comment

These show ways to swap values without using a temporary variable, not without using assignment (unless you consider op= not to be an assignment).
2

Does xor-swap count?

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

1 Comment

@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.
2
int i = 10, j = 20;
i = i + j;
j = i - j;
i = i - j;

1 Comment

I think most people think of '=' as an assignment sign.
0

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...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.