配列 レポート問題 3 解答解説

Array-3 (レベルA)

練習問題3で作った関数 dataCopy(src, dest) は,終端記号 END に出会うまで際限なく複写を行う。これでは,複写先の配列 dest のサイズを超えて複写されてしまう可能性があり,非常に危険なことである。そこで,関数を改造して, 指定されたデータ数 n 以上は複写を行わない関数,dataCopyn(src, dest, n) を作れ。( n 個目のデータの複写は行わずに,代わりに END を入れる)

 この問題は,比較的易しい.また,問題には関数値の指定はないが,何かの役に立つかも知れないので,複写したデータ数を返すこととする.まずは,関数仕様をきちんと作ることから始めよう。

int dataCopyn(int src[], int dest[], int n) の仕様
終端記号 END で終わることが約束されている整数型データ列 src の内容を,終端記号も含めて,整数型配列 dest に複写する.ただし,src[] にあるデータ数が n を超えたときには,最初の n-1 個のみを複写し,dest[n-1] に終端記号を入れる.関数戻り値は,複写したデータ数(終端記号を含まず)である.
#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]) という書き方は,配列のサイズを与える方法として,具体的な値を与えるよりも,安全なものである.