SWAP(スワップ)とは、 ま~改めていう必要もないぐらい、プログラミングの世界ではありきたりのものじゃないですかね?? ^^;)
SWAPとは、2つの変数内の値を入れ替えっこすることです。
(ほら、Linuxでは、実メモリが足りなくなって、ハードディスクに内容の一部を退避しておく場合、
そのハードディスク部分を「スワップ領域」って言うでしょ??)
Cではポインタを使用し、こんな関数を実装してみたり、
void swap(int * a, int * b)
{
int tmp = *a;
*a = *b;
*b = tmp;
}
C++では、参照を使用し、こんな関数を実装してみたり、
inline void swap(int & a, int & b)
{
int tmp = a;
a = b;
b = tmp;
}
した経験は、たぶんプログラマー歴の長い方ならば、1度や2度はあると思います ^^;)
でも、こんなマクロ↓を定義すれば、SWAPの為に、わざわざ別関数を実装しなくても良いって知ってました??
#define swap(a,b) a^=b^=a^=b
Cコード例)
#include <stdio.h>
#define swap(a, b) a^=b^=a^=b
int main(void)
{
int i, j;
i = 10;
j = 20;
printf("%d - %d\n", i, j);
swap(i, j);
printf("%d - %d\n", i, j);
return 0;
}
結果)
Oh!見事に値が入れ替わっています。
私は上記のマクロを初めて見たとき、 「スゲ~~!!(*゚∀゚)=3ムッハー 」と思わず叫んでしまいました。
・・・すいません、嘘です。叫びはしませんでした^^;)
でも、かなり驚いたのは間違いないです。
皆さんも機会があれば、このSWAPマクロを使って、同僚をビックリさせちゃいましょう!
(「こんなマクロとっくに知ってるよ~」という方は、華麗にスルーしちゃって下さいw)
ただし、以下の場合に注意が必要とのこと。
int i = 10;
swap(i, i);
ASSERT(i == 0);
同一の値を渡した場合は、i^i = 0 の為、i == 0 となり、ASSERTが発動します。
(つまり、iが0になってしまうというオチ)
後、「浮動小数点にこのマクロを使用するとヤバイ」みたいな書き込みがありましたが、
少なくともVC++2005のデフォルト設定では、floatやdouble型の値をこのマクロに渡すと、コンパイルエラーが発生します。
補足:どうして a^=b^=a^=b で値をスワップできるのか?
(2ちゃんねるで、ワザワザAAを作って説明してくれている人がいたので、それを転載します。)
非常に分かりやすいです~^^;)
おまけ:
浮動小数点でも問題なく動作するSWAPマクロ
#define swap(a,b) {a+=b;b=a-b;a-=b;}
浮動小数点でも問題なく動作するSWAPマクロ その2
#define swap(a,b) {a += b -= (a = b-a);}
トリッキーさには欠けるけれど、上で挙げた様な欠点もないし、浮動小数点をswapしたい場合には、こちらの方が良さげですね^^;)
(あ、もちろん、精度の問題とかはありますけど・・・)