无法返回C返回数组

时间:2012-09-20 18:33:33

标签: c

我在全局声明hws并尝试在此方法中返回它,但是我收到指针错误。我想知道是否有人知道为什么会这样,并建议一个解决方案?随机化只是得到一个随机数。

extern int hws[100][20];

int randomize()
{

    int value;
    int tru_fals = 0;
    value = -1;
    while ( tru_fals != 1 )
    {
        value = rand();
        if ( 0 < value )
        {
            if( 101 > value )
            {
                tru_fals = 1;
            }
        }
    }
    return value;

}
int *populate()
{

    int i, j;

    i = 0;
    j = 0;
    while( i < 20 )
    {
        while ( j < 100)
        {
            int temp = randomize();
            hws[i][j] = temp;
            j++;
        }
        i++;
    }
    return hws;

}

5 个答案:

答案 0 :(得分:2)

您定义extern int hws[100][20]; 这不会创建任何数组。它只是说在程序的某个地方,应该有一个。

为了使其工作,其他一些源文件必须真正定义数组 - int hws[100][20];(不含extern)。然后,如果你编译并链接在一起,它应该可以工作。

如果您只想要一个源文件,则更容易 - 只需删除extern

但是:刚刚注意到Serge's answer,这实际上是问题的真正原因。

答案 1 :(得分:2)

有一个错误:数组被声明为100x20,但是你会像20x100一样遍历它。

答案 2 :(得分:1)

除非它是sizeof_Alignof或一元&运算符的操作数,或者是用于初始化声明中的另一个数组的字符串文字,否则“{元素数组T”类型的>表达式将被转换(“衰减”)为“指向T的指针”类型的表达式,其值将是地址数组中的第一个元素(6.3.2.1/3)。

return hws;中的行populate中,表达式hws的类型是“{元素{1}}的20个元素数组的100个元素数组”;根据上面的规则,它将被转换为“指向int的20个元素数组的指针”或int。因此,int (*)[20]的正确声明需要

populate

读作

int (*populate())[20]
{
   ...
   return hws;
}

并且返回结果的类型也需要 populate -- populate populate() -- is a function *populate() -- returning a pointer (*populate())[20] -- to a 20-element array int (*populate())[20] -- of int.

说完了......

出于多种原因,强烈建议不要使用全局变量。最好将数组作为参数传递给int (*)[20],如下所示:

populate

你可以简单地称之为

void populate(int (*arr)[20], size_t rows)
{  
  size_t i, j;

  for (i = 0; i < rows; i++)
  {
    for (j = 0; j < 20; j++)
    {
      arr[i][j] = randomize();
    }
  }
}

如果您使用的是支持可变长度数组的编译器(C99编译器或未定义populate(hws, sizeof hws / sizeof hws[0]); 的C2011编译器或将其定义为0),则可以将该函数定义为

__STDC_NO_VLA__

并将其命名为

void populate(size_t cols, size_t rows, int (*arr)[cols]) // cols must be declared
{                                                         // before it can be used
  size_t i, j;                                            // to declare arr

  for (i = 0; i < rows; i++)
  {
    for (j = 0; j < cols; j++)
    {
      arr[i][j] = randomize();
    }
  }
}

所以你不会在任何地方硬编码。

如果您没有使用支持可变长度数组的编译器,并且您不想对函数原型中的行数进行硬编码,则可以执行以下操作:

size_t rows = sizeof hws[0] / sizeof hws[0][0];  // dividing the size of the array
size_t cols = sizeof hws / sizeof hws[0];        // by the size of the first element
populate(cols, rows, hws);                       // gives the number of elements

并将其命名为

void populate(int *arr, size_t rows, size_t cols)
{
  size_t i, j;
  for (i = 0; i < rows; i++)
  {
    for (j = 0; j < cols; j++)
    {
      arr[i * rows + j] = randomize();
    }
  }
}

在这种情况下,我们不是将指针传递给数组,而是传递指向第一个元素的指针(地址值相同,但类型为// rows and cols calculated as above populate(&hws[0][0], rows, cols); 而不是int *。所以int (*)[20]函数将其视为一维数组,并使用populate计算偏移量。请注意,此技巧仅适用于已连续分配的二维数组。

这也意味着i * rows + j可以使用任何大小的数组,而不仅仅是Nx20。

答案 3 :(得分:0)

hws是一个矩阵,它意味着它和int **

你正在返回和int *所以你的指针类型不匹配。

答案 4 :(得分:0)

首先,它不需要返回,因为它是全局的。其次,它是指向int的指针。它是一个数组的数组。