【问题标题】:C programming: get the size of a two-dimensional pointer to arraysC 编程:获取指向数组的二维指针的大小
【发布时间】:2018-02-15 13:25:57
【问题描述】:

我正在 C 中创建一个二维数组,如下所示:

int array1[] = {1,2,3,4,5,6,7,8,9,10};
int array2[] = {11,12,13,14,15};
int* array3[2] = {array1,array2};

现在我想获得两个维度的大小。对于第一个维度,如果我使用以下代码,我会得到 2 的正确结果:

int array3_x = sizeof(array3)/sizeof(*array3);    // array3_x = 2

但我无法获得另一个维度的大小。到目前为止,我已经尝试了以下方法:

for (int i = 0; i < array3_x; ++i) {
  array3_y[i] = sizeof(array3[i])/sizeof(*array3[i]);
}

我总是得到 1 的结果。有没有办法得到正确的 10 和 5 大小?

【问题讨论】:

  • 这是 C 还是 C++?如果是 C++,那么我认为不可能,你应该使用std::vector。如果是 C,那么我不知道答案,因为 VLA 很奇怪。无论哪种方式,请只标记一个。
  • 这里没有二维数组。只有 2 个一维整数数组和一个一维指针数组。
  • 你是对的 John3136,我首先有一个一维整数数组,我将它放在一个指针内。但是如何从指针中获取整数数组的大小?
  • *array3[i] 是 int 类型。它不是一个数组。问题是,您将数组退化为指针,这些指针不可能携带任何此类信息。您需要将数据存储在其他地方(或执行诸如空终止之类的操作,这很难看)。或者,如果可能,您切换到 C++。
  • 指向两个不同大小数组的容器不是二维数组。与为什么数学矩阵必须是方形的原因相同。

标签: c arrays pointers sizeof


【解决方案1】:

数组是指针的想法。他们不是。数组可以退化为指针。这里的想法是数组连续存储在内存中,所以如果我们有一个指向第一个元素的指针,我们可以使用指针算术来获取其余部分。但要明白这是指向第一个元素的指针,而不是数组。

通过键入int* array3[2] = {array1,array2};,您可以创建一个数组,该数组包含两个指向数组第一个元素的指针。这些指针不携带有关数组长度的任何信息。见过以这样的指针作为参数的函数吗?那些往往也将大小作为另一个论点。 (除了以 null 结尾的 char 数组)

因此,您必须以其他方式存储信息。习惯了 C++,我的方法是使用模仿类的结构。本质上是在模仿 C++ std::vector。也就是说,我不太习惯 C,不知道这是否是这里的标准方法。

编辑:这里很重要的是您的应用程序。最好的方法当然需要知道你想做什么。例如,如果您想要存储 2D 网格数据,我只需使用大小为 n*m 的 1D 数组。如果你想存储锯齿状的数据,你可以简单地用一个数组来存储子数组的大小。

【讨论】:

  • 与某人交谈 C++ 不是一个好主意。用 C 而不是 C++ 回答 C 问题。它们是不同的语言,而不仅仅是方言。
  • @Olaf 我到底在哪里用 C++ 与某人交谈?我这里说的是模仿 C++。
  • 您的其他帖子也这样做了,而这一篇也提到了一些 C++ 结构。模拟 C++ 通常不是一个好方法。这个问题是不必要的。如果你不懂 C,为什么要回答 C 问题?
  • @Olaf “如果你不懂 C,为什么要回答 C 问题?”是什么意思?我的意思是,我的回答实际上是对手头实际问题的回答。我的答案中最重要的部分是解释指针和数组之间的区别,这对于理解这里至关重要。我还提供了如何解决问题的功能性建议。在 C 中。听起来好像我的回答与“切换到 C++!”一样。你建议我“用 C 回答 C 问题”,我照做了。我认为我的答案是该词真正含义的答案,我有点困惑你没有。
  • 分配二维数组的同义方式是使用二维数组。不是其他构造,也不是模拟 C++ 向量。它尽可能地直截了当。
【解决方案2】:

也许这可能有效:

如果你可以将数组变成以零结尾的数组:

int  array1[]  = {1,2,3,4,5,6,7,8,9,10,0};
int  array2[]  = {11,12,13,14,15,0};
int* array3[2] = {array1,array2};

然后你可以使用这样的函数来获取每个的长度:

/********************************************************************
** Get the length of a zero-terminated int array.
*/
size_t LengthOfIntArray(int *array)
   {
   int *index = array;

   while(*index)
      ++index;

   return((size_t)(index - array));
   }

你可以像这样打印每个数组的长度:

/********************************************************************
** Program start
*/
int main(void)
   {
   int i;
   int array3_x = sizeof(array3)/sizeof(*array3);    // array3_x = 2

   printf("Height of array3: %d\n", array3_x);

   for(i = 0; i < array3_x; ++i)
      printf("Length of array3[%d]: %zd\n", i, LengthOfIntArray(array3[i]));

   return(0);
   }

输出将是:

Height of array3: 2
Length of array3[0]: 10
Length of array3[1]: 5

【讨论】:

    【解决方案3】:
    #include <stdio.h>
    #include <stdlib.h>
    
    int main() {
        int array1[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
        int array2[] = {10, 11, 12, 13, 14};
        int *array3[] = {array1, array2};
        unsigned long int c1, c2, c3;
    
        c1 = sizeof(array1) / sizeof(*array1);
        c2 = sizeof(array2) / sizeof(*array2);
        c3 = sizeof(array3) / sizeof(*array3);
    
        printf("size of array1 : %2lu\n", c1);
        printf("size of array2 : %2lu\n", c2);
        printf("size of array3 : %2lu\n", c3);
    
        /* so far, so good ...
           however, the following "printf"s will fail
           to give assumed results
        */
    
        c1 = sizeof(array3[0]) / sizeof(*array3[0]);
        c2 = sizeof(array3[1]) / sizeof(*array3[1]);
    
        printf("size of array1 : %2lu\n", c1);
        printf("size of array2 : %2lu\n", c2);
    
        return 0;
    }
    

    在您的代码中,在for 循环中的array3_y[i] = sizeof(array3[i])/sizeof(*array3[i]); 行中,array3[i] 不再 指向一个数组——编译器没有关于该变量长度的信息它指向的是一个数组、单个char 还是一个int 或其他东西——但它只是一个普通指针(可能是一个指向默认int 的指针)。

    我认为您当前的系统使用 32 位寻址 (sizeof(unsigned int) / sizeof(int));我的系统使用 64 位,结果吐出“2”(即sizeof(unsigned long int) / sizeof(int))。

    【讨论】:

    • 为什么将unsigned longunsigned long int c1, c2, c3size_tunsigned 甚至int 一起使用?由于sizeof 的返回类型与size_t 匹配,这似乎是一个初始选择。
    【解决方案4】:

    没有。你不能。编译器永远不知道你的指针指向的数组大小。

    参考:How to find the 'sizeof' (a pointer pointing to an array)?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-09
      • 1970-01-01
      • 1970-01-01
      • 2017-06-11
      • 2021-08-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多