C では、配列のサイズに関する情報は配列と共に格納されません。安全に作業するには、その大きさを知る必要があります。
これを回避するためのテクニックがいくつかあります。配列が現在のスコープで静的に宣言されている場合、サイズは次のように決定できます。
size_t size = (sizeof(a) / sizeof(a[0]);
これは、要素を追加するたびにサイズを更新する必要がない場合に便利です。
struct point a[] = {{1, 1, 1}, {2, 2, 2}};
size_t size = (sizeof(a) / sizeof(a[0));
ただし、別の場所から渡された、または例のようにポインターに変換された任意の配列がある場合は、そのサイズを決定する何らかの方法が必要になります。これを行う通常の方法は、サイズを配列とともに (別のパラメーターとして、または配列を含む構造体として) 渡すか、配列がセンチネル値 (の値) を含むことができる型である場合です。指定された型が無効である場合)、配列の最後にセンチネルを追加する必要があるよりも 1 つ大きい配列を割り当て、それを使用して最後に到達した時期を判断できます。
別の引数として長さを渡す方法は次のとおりです。
struct point myfunction(struct point array[], size_t n) {
for (size_t i = 0; i < n; ++i) {
struct point p = array[i];
// do something with p ...
}
}
または、長さを含む構造として:
struct point_array {
size_t n;
struct point elems[];
}
struct point myfunction(struct point_array a) {
for (size_t i = 0; i < a.n; ++i) {
struct point p = a.elems[i];
// do something with p ...
}
}
センチネル値を配列で直接使用するのはおそらく難しいでしょう。これはstruct point
、同じ型である明らかな無効な値がないためです。 NULL ポインターで終了するポインターの数。ポインタを配列にインラインで格納するのではなく、構造体へのポインタを格納することで、それを使用できます。char
'\0'
struct point
struct point *myfunction(struct point *a[]) {
for (size_t i = 0; a[i] != NULL; ++i) {
struct point *p = a[i];
// do something with p ...
}
}