練習問題3で作った関数 dataCopy(src, dest) は,終端記号 END に出会うまで際限なく複写を行う。これでは,複写先の配列 dest のサイズを超えて複写されてしまう可能性があり,非常に危険なことである。そこで,関数を改造して, 指定されたデータ数 n 以上は複写を行わない関数,dataCopyn(src, dest, n) を作れ。( n 個目のデータの複写は行わずに,代わりに END を入れる)
この問題は,比較的易しい.また,問題には関数値の指定はないが,何かの役に立つかも知れないので,複写したデータ数を返すこととする.まずは,関数仕様をきちんと作ることから始めよう。
#include <stdio.h>
#define END -1
int dataCopyn(int src[], int dest[], int n)
{
int i;
for (i = 0; i < n-1 && src[i] != END; i++) {
dest[i] = src[i];
}
dest[i] = END;
return i;
}
main()
{
int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, END};
int b[] = {1, 2, 3, END};
int c[5];
int i, l;
l = dataCopyn(a, c, 5);
for (i = 0; c[i] != END; i++) printf("%4d", c[i]);
printf("\n%d\n", l);
l = dataCopyn(b, c, sizeof(c)/sizeof(c[0]));
for (i = 0; c[i] != END; i++) printf("%4d", c[i]);
printf("\n%d\n", l);
}
1 2 3 4 4 1 2 3 3
二つ目の使用では,関数の第3引数を sizeof(c)/sizeof(c[0]) としている。もしも c の要素数 5 をどんな値に変更したとしても, sizeof(c)/sizeof(c[0]) の値は変更した後の要素数となる。したがって,sizeof(c)/sizeof(c[0]) という書き方は,配列のサイズを与える方法として,具体的な値を与えるよりも,安全なものである.