在 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));
但是,如果您有一个任意数组,该数组是从其他地方传入的,或者如您的示例中那样转换为指针,您将需要某种方法来确定其大小。执行此操作的常用方法是将大小与数组一起传递(作为单独的参数,或作为包含数组的结构),或者如果数组的类型可以包含一个标记值(一个值给定类型是无效的),您可以分配一个比您需要的数组大一个的数组,在数组的末尾添加一个哨兵,并使用它来确定您何时到达终点。
以下是您如何将长度作为单独的参数传递:
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
,因为没有明显的无效值仍然属于同一类型,但它们通常用于字符串(其数组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 ...
}
}