【问题标题】:how can one get the size of an array via a pointer? [duplicate]如何通过指针获取数组的大小? [复制]
【发布时间】:2013-10-11 18:08:15
【问题描述】:

对于以下场景,如何通过指针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) */
}

【问题讨论】:

  • 您对bytes 中数组的大小或数量(元素数量)感兴趣吗?

标签: c pointers


【解决方案1】:

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


旁注:这就是为什么他们说“数组衰减为指针”。它们“衰减”是因为与数组相比,指针本身包含的信息更少。

正如 nims 在将数组传递给函数时在 cmets 中指出的那样,它会自动衰减为指向第一个元素的指针 - 在函数中执行 sizeof 不会产生预期的结果。顺便说一句,还有一个C FAQ 与此有关。

【讨论】:

  • 只是为了添加一些东西:这就是为什么在将数组作为参数传递给函数时无法确定数组的大小
  • @cnicutar nims 指针似乎很有用 - 我认为您应该将其添加到您的答案中
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-05-30
      • 2021-07-23
      • 2010-09-18
      相关资源
      最近更新 更多