C プログラミング (C Programming)

[2017/11/08, H.Aman]
[← 演習のページへ戻る]

サンプルプログラム 3 の内容

整数を SIZE 個読み込み,それらを順に配列 a へ格納する.
その後に整数 m, n を読み込み,m 番目の数と n 番目の数を入れ替える.
なお,SIZE はマクロとして定義する.
 1:   #include <stdio.h>
 2:   
 3:   #define SIZE 5
 4: 
 5:   int main(void){
 6:      int a[SIZE], i, m, n, tmp;
 7:
 8:      printf("%d 個の整数を入力してください:\n", SIZE);
 9:      for ( i = 0; i < SIZE; i++ ){
10:         scanf("%d", &a[i]);
11:      }
12:
13:      printf("何番目と何番目を交換しますか:\n");
14:      scanf("%d %d", &m, &n);
15:
16:      tmp = a[m-1];
17:      a[m-1] = a[n-1];
18:      a[n-1] = tmp;
19:
20:      printf("%d 番目と %d 番目を交換した結果:\n", m, n);
21:      for ( i = 0; i < SIZE; i++ ){
22:         printf("%3d", a[i]);
23:      }
24:      printf("\n");
25:  
26:      return 0;
27:   }

プログラムの基本的な流れ

このサンプルプログラムの内容は大まかに次のようになっています:
  • 3 行目: マクロ SIZE を 5 と定義
  • 8-11 行目: SIZE 個の整数を読み込み,順番に配列 a へ格納
  • 13, 14 行目: m と n を読み込み
  • 16-18 行目: m 番目の数と n 番目の数を入れ替え
  • 20-24 行目:入れ替え後の配列の内容を表示
ここでポイントになるのは,「m 番目の数と n 番目の数を入れ替え」になります.

m 番目の数,n 番目の数

既に説明しましたが,配列の添字は 0 から始まります.
したがって,
  • 1 番目の数 ⇔ a[0]
  • 2 番目の数 ⇔ a[1]
  • 3 番目の数 ⇔ a[2]
  • ......
  • k 番目の数 ⇔ a[k-1]
  • ......
よって, m 番目の数は a[m-1] に対応しますし, n 番目の数は a[n-1] に対応します.

16-18 行目: tmp = a[m-1]; a[m-1] = a[n-1]; a[n-1] = tmp;

15:
16:      tmp = a[m-1];
17:      a[m-1] = a[n-1];
18:      a[n-1] = tmp;
19:

二つの変数の内容を入れ替えるという問題は,一見すると簡単そうなのですが,初めてだと間違いやすいところでもあります.

まずは簡単な例を使って説明します.
いま,x と y という二つの変数があり,それらの値を入れ替えたいとします.
例えば,x に 3, y に 5 が入っているとすると,
x 3     y 5 
これを次の状態に変えたいというわけです.
x 5     y 3 

これだけ見ると
   x = y;
   y = x;
でできるのでは?と思うかもしれません.
しかし残念ながら,これでは失敗します.

なぜなら,
   x = y;
を実行した時点で,それまでの x の値は y の値で上書きされてしまいます.
つまり,それまで x に入っていた 3 という値は,もうどこにもありません. y に入っていた 5 という値に上書きされてしまい,x, y とも同じ値を持つことになります:
x 5     y 5 

これを防ぐために,第三の変数を用意しておいて, 上書きされる前に x の値をそちらにコピーしておきます.

具体的には,第三の変数を tmp としたとき,
   tmp = x;
   x = y;
   y = tmp;
と書きます. これを順を追って見ていくと, 最初は
x 5     y 3     tmp?
ですが,tmp = x; により
x 5     y 3     tmp 5 
という具合いに x の値のコピーが tmp にも入ります.
次に, x = y; により,
x 3     y 3     tmp 5 
x の値は y の値で上書きされます.
ただ,元の x の値は tmp の方にとってあるので,y = tmp; として,無事に目的を達成できます:
x 3     y 5     tmp 5 

以上が基本的な値の入れ替え方法です.
サンプルプログラムでは x が a[m-1],y が a[n-1] になっています.