C 如何通过指针获得数组的大小?

C 如何通过指针获得数组的大小?,c,pointers,C,Pointers,对于以下场景,如何通过指针c获取数组a的大小(3)?解决这类问题的模式是什么 struct struct_point { int x; int y; int z; }; typedef struct struct_point point; int test_void_pointer () { point a[3] = {{1, 1, 1}, {2, 2, 2}}; void * b; point * c; b = a; c = b; /* get_size

对于以下场景,如何通过指针
c
获取数组
a
的大小(3)?解决这类问题的模式是什么

struct struct_point {
  int x;
  int y;
  int z;
};

typedef struct struct_point point;

int test_void_pointer () {
  point a[3] = {{1, 1, 1}, {2, 2, 2}};
  void * b;
  point * c;
  b = a;
  c = b;
  /* get_size_p (c) */
}

你不能。指针只是一个地址,一个数字,除了它的类型之外,它不包含任何关于它所指向的数据的信息


旁注:这就是为什么他们说“数组衰减为指针”。它们“衰减”是因为与数组相比,指针固有地保存的信息更少


正如nims在将数组传递给函数时在注释中指出的那样,它会自动衰减到指向第一个元素的指针,并且在函数中执行
sizeof
不会产生预期的结果。顺便说一句,关于这一点也有一些疑问

有一种方法可以确定数组的长度,但为此,必须使用另一个元素(如-1)标记数组的结尾。然后循环遍历它,找到这个元素。此元素的位置是长度。

在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));
但是,如果您有一个从其他地方传入的任意数组,或者像您的示例中那样转换为指针,则需要某种方法来确定其大小。通常的方法是将大小与数组一起传递(作为单独的参数,或作为包含数组的结构),或者如果数组的类型可以包含sentinel值(给定类型的值无效),您可以分配一个比需要大一点的阵列,在阵列的末尾添加一个哨兵,并使用该哨兵来确定何时到达末端

以下是如何将长度作为单独的参数传递:

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 ...
    }
}

您是对字节数组的大小感兴趣还是对元素的数量感兴趣?只是想补充一点:这就是为什么在将数组作为参数传递给functions@cnicutar
nims
指针似乎很有用-我认为您应该将它添加到您的答案中
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 *myfunction(struct point *a[]) {
    for (size_t i = 0; a[i] != NULL; ++i) {
        struct point *p = a[i];
        // do something with p ...
    }
}