您偶然发现了必须模拟从简单的1d 数组中的2d 数组的挑战。如果您查看给出的函数声明,您会看到GW *gw_build(...),它告诉您gw_build 将返回array 的struct GW。现在,理想情况下,您可以通过创建 array of pointers to struct GW 来让事情变得更简单,但很明显,任务的一部分是让您使用一个简单的结构数组。
这简化了分配,但使索引复杂化。这意味着,您对gw_build 的声明可以简单地是:
GW *gw_build(int nrows, int ncols, int pop, int rnd){
GW *list = calloc (nrows * ncols, sizeof *list);
if (!list) {
fprintf (stderr, "gw_build() error: virtual memory exhausted.\n");
return NULL;
}
return list;
}
但是挑战在于填充和引用每个,特别是如果您想要伪二维表示。该作业实际上是理解指针和索引操作的练习。谈论这个的最好方法是举例。 (注意:下面,我已经在gw.h 中包含了gw_struct 的声明,但是如果你不能这样做,只需将声明放在每个源文件中)
#ifndef _gw_header_
#define _gw_header_ 1
typedef struct gw_struct GW;
struct gw_struct {
int Alive;
int row;
int column;
int id;
};
extern GW *gw_build(int nrows, int ncols, int pop, int rnd);
#endif
#ifdef _gw_header_ 只是控制头文件包含的一个示例。它确保gw.h 仅包含一次。不能添加到头文件的可以报废。
源文件gw.c只需要分配nrows * ncols结构体,所以可以这么简单:
#include <stdio.h>
#include <stdlib.h>
#include "gw.h"
GW *gw_build(int nrows, int ncols, int pop, int rnd){
GW *list = calloc (nrows * ncols, sizeof *list);
if (!list) {
fprintf (stderr, "gw_build() error: virtual memory exhausted.\n");
exit (EXIT_FAILURE);
}
return list;
}
既标准又没有太多可讨论的。真正的工作来自包含main() 的源文件,您将在其中填充和使用gw_build 返回的数组。
#include <stdio.h>
#include "gw.h"
#define ROWS 10
#define COLS 10
int main (void) {
GW *world = gw_build (ROWS, COLS, 34, 1);
int i, j;
for (i = 0; i < ROWS; i++)
for (j = 0; j < COLS; j++)
(world + i * ROWS + j)->Alive = (i*ROWS + j) % 3;
for (i = 0; i < ROWS; i++)
for (j = 0; j < COLS; j++)
printf (" world[%2d][%2d] : %d\n", i, j, (world + i*ROWS + j)->Alive);
return 0;
}
(例如,我刚刚在Alive 之间填充了0-2 之间的值,具体取决于索引值)
当您从gw_build 收到分配的数组时,您必须从数组的开头管理offset 的填充和使用。您可以简单地使用 (0 < index < (nrows*ncols)),但使用 伪二维索引 会失败。诀窍只是找到一种使用二维数组语法计算和引用每个偏移量的方法。如果您在上面注意到,每个结构的偏移量由i * ROWS + j 访问。这允许array[i][j] 的伪二维引用,其中i 代表i * nrows 和j 只是从该地址的额外偏移量。
您还可以选择使用-> 运算符来引用如上所示的单元格,或者您可以编写一个等效的表单,使用. 运算符来引用结构成员。替代方案如下所示:
#include <stdio.h>
#include "gw.h"
#define ROWS 10
#define COLS 10
int main (void) {
GW *world = gw_build (ROWS, COLS, 34, 1);
int i, j;
for (i = 0; i < ROWS; i++)
for (j = 0; j < COLS; j++)
world[i * ROWS + j].Alive = (i * ROWS + j) % 3;
for (i = 0; i < ROWS; i++)
for (j = 0; j < COLS; j++)
printf (" world[%2d][%2d] : %d\n", i, j, world[i * ROWS + j].Alive);
return 0;
}
查看两者,如果您有任何问题,请告诉我。例如,我使用了两个#define 语句来修复nrows 和ncols。编译运行代码,你会看到输出:
$ ./bin/gwtest
world[ 0][ 0] : 0
world[ 0][ 1] : 1
world[ 0][ 2] : 2
world[ 0][ 3] : 0
world[ 0][ 4] : 1
world[ 0][ 5] : 2
world[ 0][ 6] : 0
world[ 0][ 7] : 1
world[ 0][ 8] : 2
world[ 0][ 9] : 0
world[ 1][ 0] : 1
world[ 1][ 1] : 2
world[ 1][ 2] : 0
world[ 1][ 3] : 1
world[ 1][ 4] : 2
world[ 1][ 5] : 0
world[ 1][ 6] : 1
world[ 1][ 7] : 2
world[ 1][ 8] : 0
world[ 1][ 9] : 1
world[ 2][ 0] : 2
...
world[ 8][ 8] : 1
world[ 8][ 9] : 2
world[ 9][ 0] : 0
world[ 9][ 1] : 1
world[ 9][ 2] : 2
world[ 9][ 3] : 0
world[ 9][ 4] : 1
world[ 9][ 5] : 2
world[ 9][ 6] : 0
world[ 9][ 7] : 1
world[ 9][ 8] : 2
world[ 9][ 9] : 0