C# 不使用临时变量交换两个变量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/804706/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Swap two variables without using a temporary variable
提问by Sreedhar
I'd like to be able to swap two variables without the use of a temporary variable in C#. Can this be done?
我希望能够在不使用 C# 中的临时变量的情况下交换两个变量。这能做到吗?
decimal startAngle = Convert.ToDecimal(159.9);
decimal stopAngle = Convert.ToDecimal(355.87);
// Swap each:
// startAngle becomes: 355.87
// stopAngle becomes: 159.9
采纳答案by Willem Van Onsem
First of all, swapping without a temporary variable in a language as C# is a very bad idea.
首先,在没有 C# 语言中的临时变量的情况下进行交换是一个非常糟糕的主意。
But for the sake of answer, you can use this code:
但是为了回答,您可以使用以下代码:
startAngle = startAngle + stopAngle;
stopAngle = startAngle - stopAngle;
startAngle = startAngle - stopAngle;
Problems can however occur with rounding off if the two numbers differ largely. This is due to the nature of floating point numbers.
但是,如果两个数字相差很大,则四舍五入可能会出现问题。这是由于浮点数的性质。
If you want to hide the temporary variable, you can use a utility method:
如果要隐藏临时变量,可以使用实用方法:
public static class Foo {
public static void Swap<T> (ref T lhs, ref T rhs) {
T temp = lhs;
lhs = rhs;
rhs = temp;
}
}
回答by Jens Alfke
Not in C#. In native code you might be able to use the triple-XOR swap trick, but not in a high level type-safe language. (Anyway, I've heard that the XOR trick actually ends up being slower than using a temporary variable in many common CPU architectures.)
不是在 C# 中。在本机代码中,您可能可以使用三重异或交换技巧,但不能在高级类型安全语言中使用。(无论如何,我听说 XOR 技巧实际上比在许多常见的 CPU 架构中使用临时变量要慢。)
You should just use a temporary variable. There's no reason you can't use one; it's not like there's a limited supply.
你应该只使用一个临时变量。没有理由不能使用它;这不像是有限的供应。
回答by BCS
For binary types you can use this funky trick:
对于二进制类型,您可以使用这个时髦的技巧:
a %= b %= a %= b;
As long as a and b are not the exact same variable (e.g. aliases for the same memory) it works.
只要 a 和 b 不是完全相同的变量(例如相同内存的别名),它就可以工作。
回答by Paul Sonier
Yes, use this code:
是的,使用此代码:
stopAngle = Convert.ToDecimal(159.9);
startAngle = Convert.ToDecimal(355.87);
The problem is harder for arbitrary values. :-)
对于任意值,这个问题更难。:-)
回答by BenAlabaster
<deprecated>
<已弃用>
You can do it in 3 lines using basic math - in my example I used multiplication, but simple addition would work also.
您可以使用基本数学在 3 行中完成 - 在我的示例中,我使用了乘法,但简单的加法也可以。
float startAngle = 159.9F;
float stopAngle = 355.87F;
startAngle = startAngle * stopAngle;
stopAngle = startAngle / stopAngle;
startAngle = startAngle / stopAngle;
Edit: As noted in the comments, this wouldn't work if y = 0 as it would generate a divide by zero error which I hadn't considered. So the +/- solution alternatively presented would be the best way to go.
编辑:如评论中所述,如果 y = 0,这将不起作用,因为它会产生我没有考虑过的除以零错误。因此,交替提出的 +/- 解决方案将是最好的方法。
</deprecated>
</弃用>
To keep my code immediately comprehensible, I'd be more likely to do something like this. [Always think about the poor guy that's gonna have to maintain your code]:
为了让我的代码立即易于理解,我更有可能做这样的事情。[总是想想那个必须维护你的代码的可怜人]:
static bool Swap<T>(ref T x, ref T y)
{
try
{
T t = y;
y = x;
x = t;
return true;
}
catch
{
return false;
}
}
And then you cando it in one line of code:
然后你可以在一行代码中完成它:
float startAngle = 159.9F
float stopAngle = 355.87F
Swap<float>(ref startAngle, ref stopAngle);
Or...
或者...
MyObject obj1 = new MyObject("object1");
MyObject obj2 = new MyObject("object2");
Swap<MyObject>(ref obj1, ref obj2);
Done like dinner...you can now pass in any type of object and switch them around...
像晚餐一样完成......你现在可以传递任何类型的对象并切换它们......
回答by paxdiablo
The rightway to swap two variables is:
交换两个变量的正确方法是:
decimal tempDecimal = startAngle;
startAngle = stopAngle;
stopAngle = tempDecimal;
In other words, use a temporary variable.
换句话说,使用临时变量。
There you have it. No clever tricks, no maintainers of your code cursing you for decades to come, no entries to The Daily WTF, and no spending too much time trying to figure out why you needed it in one operation anyway since, at the lowest level, even the most complicated language feature is a series of simple operations.
你有它。没有聪明的技巧,没有代码的维护者在未来几十年诅咒你,没有The Daily WTF 的条目,也没有花太多时间试图弄清楚为什么你在一个操作中需要它,因为在最低级别,即使是最复杂的语言特征是一系列简单的操作。
Just a very simple, readable, easy to understand, t = a; a = b; b = t;
solution.
只是一个非常简单、可读、易于理解的t = a; a = b; b = t;
解决方案。
In my opinion, developers who try to use tricks to, for example, "swap variables without using a temp" or "Duff's device" are just trying to show how clever they are (and failing miserably).
在我看来,尝试使用技巧的开发人员,例如,“不使用临时变量交换变量”或“达夫的设备”只是想展示他们是多么聪明(并且失败得很惨)。
I liken them to those who read highbrow books solely for the purpose of seeming more interesting at parties (as opposed to expanding your horizons).
我把他们比作那些阅读高雅书籍的人,只是为了在聚会上看起来更有趣(而不是扩大你的视野)。
Solutions where you add and subtract, or the XOR-based ones, are less readable and most likely slower than a simple "temp variable" solution (arithmetic/boolean-ops instead of plain moves at an assembly level).
添加和减去或基于 XOR 的解决方案的可读性较差,并且很可能比简单的“临时变量”解决方案(算术/布尔操作而不是程序集级别的简单移动)慢。
Do yourself, and others, a service by writing good quality readable code.
通过编写高质量的可读代码为自己和他人提供服务。
That's my rant. Thanks for listening :-)
那是我的咆哮。谢谢收听 :-)
As an aside, I'm quite aware this doesn't answer your specific question (and I'll apologise for that) but there's plenty of precedent on SO where people have asked how to do something and the correct answer is "Don't do it".
顺便说一句,我很清楚这并没有回答你的具体问题(我会为此道歉)但是在 SO 上有很多先例,人们问如何做某事,正确的答案是“不要做”。
回答by thecoop
For completeness, here is the binary XOR swap:
为了完整起见,这里是二进制 XOR 交换:
int x = 42;
int y = 51236;
x ^= y;
y ^= x;
x ^= y;
This works for all atomic objects/references, as it deals directly with the bytes, but may require an unsafe context to work on decimals or, if you're feeling really twisted, pointers. And it may be slower than a temp variable in some circumstances as well.
这适用于所有原子对象/引用,因为它直接处理字节,但可能需要一个不安全的上下文来处理小数,或者,如果你感觉真的很扭曲,指针。在某些情况下,它也可能比临时变量慢。
回答by thecoop
a = a + b
b = a - b
a = a - b
?
?
回答by this. __curious_geek
int a = 4, b = 6;
a ^= b ^= a ^= b;
Works for all types including strings and floats.
适用于所有类型,包括字符串和浮点数。
回答by Codzart
Beware of your environment!
小心你的环境!
For example, this doesn't seem to work in ECMAscript
例如,这似乎不适用于 ECMAscript
y ^= x ^= y ^= x;
But this does
但这确实
x ^= y ^= x; y ^= x;
My advise? Assume as little as possible.
我的建议?尽量少假设。