この方程式は、一時変数なしで2つの数値を交換しますが、算術演算を使用します。
a = (a+b) - (b=a);
算術演算なしでそれを行うにはどうすればよいですか?私はXORについて考えていました。
a=a+b;
b=a-b;
a=a-b;
これはシンプルでありながら効果的です。
Cでは、これは機能するはずです。
a = a^b;
b = a^b;
a = a^b;
または、かっこいい/かっこいい人:
a^=b;
b^=a;
a^=b;
詳細については、 this をご覧ください。 XORは非常に強力な操作であり、あちこちで多くの興味深い使用法があります。
なぜ標準ライブラリを使用しないのですか?
std::swap(a,b);
一時的なストレージまたは算術演算を使用せずに2つの数値を交換する最良の方法は、両方の変数をレジスターにロードし、そのレジスターを逆に使用することです!
あなたはCから直接それを行うことはできませんが、コンパイラはおそらくあなたのためにそれをうまく機能させる可能性があります(少なくとも、最適化が有効になっている場合)-KennyTMが彼のコメントで提案したような単純で明白なコードを書く場合。
例えば.
void swap_tmp(unsigned int *p)
{
unsigned int tmp;
tmp = p[0];
p[0] = p[1];
p[1] = tmp;
}
-O2
最適化フラグを使用してgcc 4.3.2でコンパイルすると、次の結果が得られます。
swap_tmp:
pushl %ebp ; (prologue)
movl %esp, %ebp ; (prologue)
movl 8(%ebp), %eax ; EAX = p
movl (%eax), %ecx ; ECX = p[0]
movl 4(%eax), %edx ; EDX = p[1]
movl %ecx, 4(%eax) ; p[1] = ECX
movl %edx, (%eax) ; p[0] = EDX
popl %ebp ; (epilogue)
ret ; (epilogue)
XORを使用して、
void swap(int &a, int &b)
{
a = a ^ b;
b = a ^ b;
a = a ^ b;
}
XOR付きのライナー1つ、
void swap(int &a, int &b)
{
a ^= b ^= a ^= b;
}
これらのメソッドはテストケースで失敗しないため、クリーンであるように見えますが、変数の値は同じシーケンスポイント内で2回変更されるため、(メソッド2のように)未定義の動作が宣言されていると言われていますANSI C.
私は以前にこのCソリューションを見たことがありませんが、誰かがそれを考えたと確信しています。そして、おそらく私よりも多くの自制心がありました。
fprintf(fopen("temp.txt", "w"), "%d", a);
a = b;
fscanf(fopen("temp.txt", "r"), "%d", &b);
追加の変数はありません!
私にとってはうまくいきますが、stdioの実装によっては、出力バッファリングについて何かしなければならない場合があります。
a =((a = a + b)-(b = a-b));
乗算と除算も使用できます。
int x = 10, y = 5;
// Code to swap 'x' and 'y'
x = x * y; // x now becomes 50
y = x / y; // y becomes 10
x = x / y; // x becomes 5
値の1つが符号付き整数の範囲外の場合、上記の解決策に加えて、2つの変数の値をこのように交換できます
a = a+b;
b=b-(-a);
a=b-a;
b=-(b);