0

我全局声明 hws 并尝试在此方法中返回它,但出现指针错误。我想知道是否有人知道这是为什么并且可以提出解决方案?Randomize 只是得到一个随机数。

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;

}
4

5 回答 5

2

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

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

如果您只想要一个源文件,那就容易多了——只需删除extern.

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

于 2012-09-20T18:38:16.727 回答
2

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

于 2012-09-20T18:40:45.097 回答
1

除非它是sizeof, _Alignof, 或一元运算符的操作数&,或者是用于在声明中初始化另一个数组的字符串文字,否则“N-element array of”类型的表达式T将被转换(“decay”)为“pointer to T”类型的表达式,其值将是数组中第一个元素的地址(6.3.2.1/3)。

在行return hws;populate,表达式的类型hws是“100 元素数组的 20 元素数组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();
    }
  }
}

你可以简单地称之为

populate(hws, sizeof hws / sizeof hws[0]);

如果您使用的是支持可变长度数组的编译器(C99 编译器或未定义__STDC_NO_VLA__或将其定义为 0 的 C2011 编译器),您可以将函数定义为

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

所以你不会在任何地方对 20 进行硬编码。

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

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. 请注意,此技巧仅适用于已连续分配的 2D 数组。

这也意味着它populate可以处理任何大小的数组,而不仅仅是 Nx20。

于 2012-09-20T18:59:52.720 回答
0

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

您正在返回并且 int * 所以您的指针类型不匹配。

于 2012-09-20T18:36:30.550 回答
0

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

于 2012-09-20T18:38:34.587 回答