使用指针获取数组的长度

6

当我只知道指向数组的指针时,有没有一种方法可以获得数组的长度?

请参考以下示例:

int testInt[3];
testInt[0] = 0;
testInt[1] = 1;
testInt[2] = 1;

int* point;
point = testInt;

Serial.println(sizeof(testInt) / sizeof(int)); // returns 3
Serial.println(sizeof(point) / sizeof(int)); // returns 1

(这是来自Arduino代码的片段 - 很抱歉,我不会“说”真正的C语言)。

6个回答

13

简单的回答是否定的。您可能希望在内存中保留一个变量,以存储数组中的项目数量。

不太简单的答案是,有一种方法可以确定数组的长度,但是您必须使用另一个元素(例如-1)标记数组的结尾。然后只需循环遍历它并查找此元素。该元素的位置就是数组的长度。但是,这无法与您当前的代码配合使用。

从以上两种方法中选择一种。


1
@WTP 对于C++来说也是一样的,只不过std::vector会为你处理它。 - Tom van der Woerdt

5

这里也在进行一个Arduino项目…… 互联网上的每个人似乎都坚称这是不可能的…… 然而,书中最古老的技巧使用空终止数组似乎完全可行。

char指针的示例:

    int getSize(char* ch){
      int tmp=0;
      while (*ch) {
        *ch++;
        tmp++;
      }return tmp;}

magic...


4
对于字符数组,你可以使用strlen()函数轻松地获取它的大小,因为它使用与上面相同的方法。但对于数字字符数组,你无法这样做。 - Yen NQ

3
  • 如果您有一个数组变量,您可以推断出数组的长度。
  • 如果您只有指向数组的指针,则无法推断出数组的长度。

1

你不能也不应该尝试使用指针算术来推断数组长度

如果在C++中,请使用vector类


1

如果你指向整个数组而不是指向第一个元素,那么你就可以这样做:

int testInt[3];
int (*point)[3];
point = testInt;

printf( "number elements: %lu", (unsigned long)(sizeof*point/sizeof**point) );
printf( "whole array size: %lu", (unsigned long)(sizeof*point) );

除非你已经知道长度,否则计数没有什么用处。 - Tom van der Woerdt

0
当我只知道指向数组的指针时,有没有办法获取数组的长度?
从技术上讲,如果代码具有真正的数组指针,则可以通过类型获得数组大小,例如int (*array_pointer)[3]
这与 OP 的代码不同,因为指针point不是指向数组的指针,而是指向int指针point = testInt;这一行将数组testInt转换为数组第一个元素的地址(即int *),并将其分配给point。因此,数组大小信息丢失了。
int testInt[3];
testInt[0] = 0;
testInt[1] = 1;
testInt[2] = 1;

int* point;
point = testInt;                     // Get the address of testInt[0]

int (*array_pointer)[3] = &testInt;  // Get the address of the array

printf("%zu\n", sizeof(testInt) / sizeof(int));
printf("%zu\n", sizeof(point) / sizeof(int));
printf("%zu\n", sizeof(*point) / sizeof(int));
printf("%zu\n", sizeof(*array_pointer) / sizeof(int));

printf("%p\n", (void *) testInt);
printf("%p\n", (void *) point);
printf("%p\n", (void *) array_pointer);

示例输出

3
2
1
3

0xffffcbc4
0xffffcbc4
0xffffcbc4

指针pointarray_pointer都有指向内存中相同位置的值,但指针的类型不同。


使用支持变长数组的 C99 或更高版本,可以编写下面的代码并获得类似的结果,而无需在指针定义中明确编码 3。

int (*array_pointer_vla)[sizeof testInt/sizeof testInt[0]] = &testInt;
printf("%zu\n", sizeof(*array_pointer_vla) / sizeof(int));

输出

3

我现在看到了与@user411313的答案的相似之处。也许更深入的解释和VLA讨论会很有用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接