昨日の続きです.
関数が配列を受け取るときには,配列のサイズ(要素数)をどうやって獲得するか,ちょっと配慮しないといけません.というのも,「関数が配列を受け取る」とき,その仮引数は,常にポインタになるからです.「void selection_sort(int array[6])」と書いても,arrayはポインタ変数です.
さてarrayが配列変数なら,sizeof(array) / sizeof(array[0])によってその要素数を求められます*1が,arrayがポインタ変数ではできません.関数の仮引数に限らず,int *array;のとき,sizeof(array) / sizeof(array[0])は,sizeof(int *) / sizeof(int)として計算されます.
関数が,参照渡しで配列を受け取るときに,その要素数を獲得する方法には,次の3通りが考えられます.状況によって,いずれか一つを選ぶといいでしょう.
#define ARRAY_SIZE 6 … void selection_sort(int *array) { /* 配列の要素数は ARRAY_SIZE */ } … int array[ARRAY_SIZE] = {3, 1, 4, 5, 9, 2}; selection_sort(array);
void selection_sort(int *array, int size) { /* 配列の要素数は size */ } … int array[] = {3, 1, 4, 5, 9, 2}; selection_sort(array, sizeof(array) / sizeof(array[0]));
- 配列の末尾に,番兵を置きます.配列の途中に意図的に番兵を置くこともできます.ただし個人的には,この書き方はお勧めしません.というのも,上述の「配列の要素数も引数として渡す」ほうが優れているからです.人のコードを読んでいて,配列の末尾が0だったり負だったり,文字列の配列ならNULLだったりしたときに,番兵かなと思ってください.
#define ARRAY_SIZE 6 … void selection_sort(int *array) { /* 配列の要素数は,番兵から求める */ } … int array[ARRAY_SIZE] = {3, 1, 4, 5, 9, 2, -1}; selection_sort(array);
*1:関数の中のローカル変数として配列を定義する場合にも,この式で求められます.