【问题标题】:Get length of an Array using a pointer使用指针获取数组的长度
【发布时间】:2011-12-11 14:21:51
【问题描述】:

当我只知道一个指向数组的指针时,有没有办法获取数组的长度?

看下面的例子

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)。

【问题讨论】:

    标签: c arrays pointers arduino


    【解决方案1】:

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

    还有一个不那么简单的答案。有一种方法可以确定数组的长度,但为此您必须用另一个元素标记数组的结尾,例如-1。然后遍历它并找到这个元素。这个元素的位置就是长度。但是,这不适用于您当前的代码。

    从上面选择一个。

    【讨论】:

    • @WTP 与 C++ 相同,但 std::vector 会为您处理。
    【解决方案2】:

    还在这里做一个 Arduino 项目... 互联网上的每个人似乎都坚持认为这是不可能的...... 然而,书中最古老的技巧似乎对空终止数组也能正常工作......

    字符指针示例:

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

    魔法...

    【讨论】:

    • 对于 char 数组,您可以使用 strlen() 轻松获取其大小,因为它使用与上图相同的方法。但是对于数字字符数组,你不能。
    【解决方案3】:
    • 如果有数组变量,则可以推断出数组的长度。
    • 如果只有一个指向数组的指针,则无法推断数组的长度。

    【讨论】:

      【解决方案4】:

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

      如果在 C++ 中使用向量类

      【讨论】:

        【解决方案5】:

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

        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) );
        

        【讨论】:

        • 除非在这种情况下你必须已经知道长度,这使得计数毫无用处。
        【解决方案6】:

        当我只知道一个指向数组的指针时,有没有办法获取数组的长度?

        技术上是的,有一种方法可以让代码有一个真正的指向数组的指针,因为数组大小的类型与int (*array_pointer)[3] 相同。

        这与 OP 的代码不同,因为指针 point不是指向数组的指针,而是 pointer to an 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
        

        指针point 和array_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 讨论会很有用。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-03-04
          • 1970-01-01
          • 1970-01-01
          • 2023-03-09
          • 1970-01-01
          • 1970-01-01
          • 2013-03-24
          • 2021-09-12
          相关资源
          最近更新 更多