【C#入門】配列の値を入れ替えるには?一時変数と「コピー」の仕組みを図で理解しよう

広告

配列に入っている2つの値を交換したいとき、なぜ「一時変数」が必要なのでしょうか。

人間なら、右手と左手に持ったものを同時に持ち替えるように考えられます。しかし、プログラムの代入は、右辺の値を左辺へコピーする処理です。2つの値を同時に交換する処理ではありません。

この記事では、配列を「ロッカー」、一時変数を「引き出し」にたとえて、値を交換する仕組みを説明します。

配列の2つの値を一時変数で交換する3ステップ。配列をロッカー、一時変数を引き出しにたとえた図
配列の値交換を、一時変数(引き出し)を使う3ステップで表した図

そのまま代入すると、元の値が消えてしまう

次の2つの値を交換する場面を考えます。

A[1] = 5
A[2] = 2

最終的に、次の状態にしたいとします。

A[1] = 2
A[2] = 5

ここで、先に A[1] ← A[2] と代入すると、A[2] の2が A[1] にコピーされます。

A[1] = 2
A[2] = 2

A[1] に入っていた5は上書きされ、使えなくなりました。この状態からでは、元の5を A[2] に入れることができません。

そこで、上書きされる前の値を一時的に保存する場所が必要になります。それが一時変数です。

一時変数を使う3つの手順

一時変数を temp とすると、交換は次の3ステップで行えます。

1. A[1]の値を一時変数へコピーする

手順1。A[1]の5を一時変数へコピーし、配列にも元の5が残っている状態
手順1:A[1]の値を一時変数へコピー

実行する処理(図の表記)

temp ← A[1]

実行前

A[1] = 5
A[2] = 2
temp = 未設定

実行後

A[1] = 5   // 変わらない
A[2] = 2   // 変わらない
temp = 5   // A[1]の値がコピーされた

temp ← A[1] を実行すると、A[1] の5が temp にコピーされます。元の値は移動していないため、A[1] にも5が残ります。

2. A[2]の値をA[1]へコピーする

手順2。A[2]の2をA[1]へコピーし、一時変数の5は保持されている状態
手順2:A[2]の値をA[1]へコピー

実行する処理(図の表記)

A[1] ← A[2]

実行前

A[1] = 5
A[2] = 2
temp = 5

実行後

A[1] = 2   // A[2]の値がコピーされた
A[2] = 2   // 変わらない
temp = 5   // 変わらない

A[1] ← A[2] を実行すると、A[1] は2で上書きされます。元の5は、手順1で temp にコピーしてあるため失われません。

3. 一時変数の値をA[2]へコピーする

手順3。一時変数の5をA[2]へコピーして値の交換を完了する様子
手順3:一時変数の値をA[2]へコピー

実行する処理(図の表記)

A[2] ← temp

実行前

A[1] = 2
A[2] = 2
temp = 5

実行後

A[1] = 2   // 変わらない
A[2] = 5   // tempの値がコピーされた
temp = 5   // 使い終わった値が残っている

A[2] ← temp を実行すると、保存しておいた5が A[2] にコピーされ、値の交換が完了します。temp に残っている5は、この後使わないため問題ありません。

交換後。A[1]が2、A[2]が5になり、2つの値が入れ替わった状態
交換後:A[1]とA[2]の値が入れ替わった

C#で書いてみよう

図では説明を分かりやすくするために A[1]A[2] を使っています。ただし、C#の配列番号(インデックス)は0から始まります

したがって、C#では次のように書きます。

int[] numbers = { 5, 2 };

int temp = numbers[0];
numbers[0] = numbers[1];
numbers[1] = temp;

Console.WriteLine(numbers[0]); // 2
Console.WriteLine(numbers[1]); // 5
図の表現C#のコード意味
一時 ← A[1]temp = numbers[0];最初の値を保存する
A[1] ← A[2]numbers[0] = numbers[1];2番目の値を最初の場所へコピーする
A[2] ← 一時numbers[1] = temp;保存していた値を2番目の場所へコピーする

「移動」ではなく「コピー」と考える

代入を理解するときの大切なポイントは、値が箱から箱へ移動するのではなく、右辺の内容が左辺へコピーされると考えることです。

たとえば、numbers[0] = numbers[1]; を実行しても、代入元の numbers[1] は消えません。変化するのは代入先の numbers[0] です。

なお、この説明は int などの値型を前提にしています。クラスなどの参照型を代入する場合は、オブジェクトそのものではなく、同じオブジェクトを指す参照がコピーされます。

C#では短く書く方法もある

C#では、タプルを利用して次のように交換することもできます。

(numbers[0], numbers[1]) = (numbers[1], numbers[0]);

短く便利な書き方ですが、最初は一時変数を使う3ステップを理解しておくことをおすすめします。上書きとコピーの仕組みが分かるため、代入を使うほかの処理も理解しやすくなるからです。

まとめ

  • 代入は、右辺の値を左辺へコピーする処理
  • 先に上書きすると、交換に必要な元の値を失ってしまう
  • 上書き前の値は、一時変数に保存する
  • 値の交換は「一時変数へ保存 → 上書き → 保存した値を戻す」の3ステップ
  • C#の配列インデックスは0から始まる

一時変数は、値を安全に持ち替えるための「一時的な引き出し」です。図とコードを対応させながら、3つの代入を順番に追ってみてください。

訪問数 31 回, 今日の訪問数 33回

広告

C#,入門,変数,配列

Posted by hidepon