練習問題2: 整数型配列 array の,array[0] から array[n-1] までの n 個の要素の内容を逆順に並べ替える関数 arrayReverse(int array[], int n) を作れ。
まずは,関数仕様をきちんと書くことから始めよう。
上の仕様の関数を作るのであるが,その内容にはいつくかの書き方がある。 その代表的なものを二つあげて,書きやすさ,間違いにくさなどを比較してみよう。
次の関数は, for 文の中で i を 0, 1, ..., n/2-1 まで動かして, a[i] と a[n-1-i] とを入れ替えている。
void arrayReverse(int array[], int n) { int i, x; for (i = 0; i < n/2; i++) { x = array[i]; array[i] = array[n-1-i]; array[n-1-i] = x; } }
array[0] と array[n-1]とを入れ替え,array[1] と array[n-2] とを入れ替え, ....,array[n/2-1] と array[n-n/2] とを入れ替えると,逆順の並べ替えが完了する.ここで, n/2 は整数値同士の割算であるので,割り切れない場合は余りは切り捨てられることに注意しよう.
次の図を見ながら,n が偶数のときも奇数のときもうまく行っていることを確認して欲しい.(n が奇数のとき,array[n/2] は動かす必要がないことに注意)
落ち着いて作れば,間違えようのない簡単な手続きなのであるが, i < n/2 というfor 文の繰り返し条件は,プログラミングに慣れた人でも間違えやすい。
先ほどのコーディング方法だと,繰り返し条件および array[i] と入れ替える相手 array[n-1-i] がわかりにくく,間違いの原因となる。そこで,次のように、入れ替える二つの要素の添字を二つの変数 i, j で表してコーディングする方法もある。この方が、値を入れ替えるべき2要素 array[i] と array[j] が明白であり,繰り返し条件 i < j
も分かりやすく、コーディングをするときに間違いが少ないと思われる。
void array_reverse(int array[], int n) { int i, j, x; for (i = 0, j = n-1; i < j; i++, j--) { x = array[i]; array[i] = array[j]; array[j] = x; } }
このコーディングにあるように, for (..., ..., ...) の ... の部分には,カンマ演算子 "," で区切って,複数個の式を書いてもよいことを憶えておこう。