わさっきhb

大学(教育研究)とか ,親馬鹿とか,和歌山とか,とか,とか.

二つの値を交換する方法

同一の型の二つの変数があって(int x, y;としましょう.そして,あらかじめそれぞれに値が代入されているとしましょう),その値を交換するには,通常,次のように書きます.

{
  int tmp;

  tmp = x;
  x = y;
  y = tmp;
}

このtmpという名前の変数は,一時的に値を保存するためのもので,語源はtemporaryです.この変数の有効範囲を限定するため,「{」と「}」とで囲っておきます(xとyは,この外で定義されているものとします).プログラミングの授業では,if文などの制御文を使うときや,関数を定義するときに,「{」と「}」と使う,と教えていますが,処理の途中でいきなり「{」と「}」で囲っても問題ありません(ただし見た人はぎょっとするかもしれません).
以下は,非実用的なお遊びです*1
他に変数を使うことなく,整数型の二つの変数の値を交換する方法があります.こう書きます.

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

Cでは「^」は,ビットごとの排他的論理和(XOR)を求める演算子です.
なぜこれでうまくいくのかは,1ビットの演算(ブール代数)でうまくいくこと,すなわち

X1 = X XOR Y
Y1 = X1 XOR Y = (X XOR Y) XOR Y = X XOR Y XOR Y = X XOR (Y XOR Y) = X XOR 0 = X
X2 = X1 XOR Y1 = (X XOR Y) XOR X = Y

を確認して,それから,ビットごとの演算に適用するといいでしょう.
これは,排他的論理和だからなせること,ではありません.加減算や乗除算でもできます.

int x = 1, y = -1;
double a = 3, b = 5;

x = x + y;
y = x - y;  // y = 1
x = x - y;  // x = -1

a = a * b;
b = a / b;  // b = 5
a = a / b;  // a = 3

ただし乗除算の場合は,0を交換することができません.加減算にせよ乗除算にせよ,値の範囲や,丸め誤差,情報落ちなどに注意しないといけません.

*1:研究や業務の中でこんなコードを書いたら,先生なり先輩なり上司なりが「やめなさい.tmpを使いなさい」と指導するはずです.