我怎么能让一个结构有一个未知大小的数组成员?
how can i have a struct have an unknown size array member?
我试图用 c 语言制作一种扫雷克隆,但我不知道如何创建结构的可变长度数组成员并对其进行初始化。
我的结构定义
typedef struct Cell
{
Rectangle area; // The area the cell covers
bool hasMine; // If the cell covers a mine
bool covered; // If the cell is currently covered
int touching; // How many mines the cell is touching
} Cell;
typedef struct Minefield
{
int columns; // The amount of columns
int rows; // The amount of rows
int mines; // The amount of mines
Cell field[]; // An array of columns*rows Cells
} Minefield;
我如何创建雷区的新实例
Minefield NewGame(int columns, int rows, int mines)
{
int i = 0;
Cell cells[columns*rows];
for (i=0; i < columns*rows; i++) {
int x = 0;
int y = 0;
if (i == 0) {
Rectangle area = (Rectangle){0, 0, cellsize, cellsize};
cells[i] = (Cell){area, false, true, 0};
}
else {
Cell previous = cells[i-1];
x = previous.area.x + cellsize;
y = previous.area.y + cellsize;
Rectangle area = (Rectangle){x, y, cellsize, cellsize};
cells[i] = (Cell){area, false, true, 0};
}
}
Minefield field = (Minefield){columns, rows, mines, cells};
return field;
}
我是 c 的新手,我在谷歌上搜索过一些非常相似的问题,但我无法真正理解它们或它们给出的示例。我认为你可以用 gcc 扩展来做我的错误代码试图做的(或非常相似的事情),但我希望我的代码是可移植的。我怎样才能让结构具有未知大小的数组成员?
不幸的是,C 没有像 python 这样的 built-in 动态数组。但是,如果你想使用一些动态数组,你可以自己实现或者你可以看到 link C dynamically growing array 的答案,它解释了你需要有一个默认大小的起始数组,然后您可以增加数组的大小,这取决于您的算法。导入@casablance 提供的头文件后,您可以简单地将它用于您的扫雷游戏。
是的,它叫做 flexible array member
。它通常与动态分配的对象一起使用。但是,您不能按值 return Minefield
。如果数组 Minefield::field
的长度为 0
.
,编译器将仅复制 sizeof(Minefield)
数据,对象的大小是多少
你可以这样做:
Minefield* NewGame(int columns, int rows, int mines)
{
Cell cells[columns*rows];
...
// allocate memory for Minefield and cells array just after it
Minefield* minefield = malloc(sizeof(*minefield) + sizeof cells);
if (!minefield) { ... error handling ... }
// set normal fields using compund literal
*minefield = (Minefield){columns, rows, mines};
// copy cells `array` to `minefield->field` array
memcpy(minefield->field, cells, sizeof cells);
return minefield;
}
可以通过先分配Minefield
并直接写入field
成员来避免memcpy
。
Minefield* NewGame(int columns, int rows, int mines)
{
Minefield* minefield = malloc(sizeof(Minefield) + rows * columns * sizeof(Cell));
if (!minefield) { ... error handling ... }
*minefield = (Minefield){columns, rows, mines};
Cell *cells = minefield->field;
...
return minefield;
}
我试图用 c 语言制作一种扫雷克隆,但我不知道如何创建结构的可变长度数组成员并对其进行初始化。
我的结构定义
typedef struct Cell
{
Rectangle area; // The area the cell covers
bool hasMine; // If the cell covers a mine
bool covered; // If the cell is currently covered
int touching; // How many mines the cell is touching
} Cell;
typedef struct Minefield
{
int columns; // The amount of columns
int rows; // The amount of rows
int mines; // The amount of mines
Cell field[]; // An array of columns*rows Cells
} Minefield;
我如何创建雷区的新实例
Minefield NewGame(int columns, int rows, int mines)
{
int i = 0;
Cell cells[columns*rows];
for (i=0; i < columns*rows; i++) {
int x = 0;
int y = 0;
if (i == 0) {
Rectangle area = (Rectangle){0, 0, cellsize, cellsize};
cells[i] = (Cell){area, false, true, 0};
}
else {
Cell previous = cells[i-1];
x = previous.area.x + cellsize;
y = previous.area.y + cellsize;
Rectangle area = (Rectangle){x, y, cellsize, cellsize};
cells[i] = (Cell){area, false, true, 0};
}
}
Minefield field = (Minefield){columns, rows, mines, cells};
return field;
}
我是 c 的新手,我在谷歌上搜索过一些非常相似的问题,但我无法真正理解它们或它们给出的示例。我认为你可以用 gcc 扩展来做我的错误代码试图做的(或非常相似的事情),但我希望我的代码是可移植的。我怎样才能让结构具有未知大小的数组成员?
不幸的是,C 没有像 python 这样的 built-in 动态数组。但是,如果你想使用一些动态数组,你可以自己实现或者你可以看到 link C dynamically growing array 的答案,它解释了你需要有一个默认大小的起始数组,然后您可以增加数组的大小,这取决于您的算法。导入@casablance 提供的头文件后,您可以简单地将它用于您的扫雷游戏。
是的,它叫做 flexible array member
。它通常与动态分配的对象一起使用。但是,您不能按值 return Minefield
。如果数组 Minefield::field
的长度为 0
.
sizeof(Minefield)
数据,对象的大小是多少
你可以这样做:
Minefield* NewGame(int columns, int rows, int mines)
{
Cell cells[columns*rows];
...
// allocate memory for Minefield and cells array just after it
Minefield* minefield = malloc(sizeof(*minefield) + sizeof cells);
if (!minefield) { ... error handling ... }
// set normal fields using compund literal
*minefield = (Minefield){columns, rows, mines};
// copy cells `array` to `minefield->field` array
memcpy(minefield->field, cells, sizeof cells);
return minefield;
}
可以通过先分配Minefield
并直接写入field
成员来避免memcpy
。
Minefield* NewGame(int columns, int rows, int mines)
{
Minefield* minefield = malloc(sizeof(Minefield) + rows * columns * sizeof(Cell));
if (!minefield) { ... error handling ... }
*minefield = (Minefield){columns, rows, mines};
Cell *cells = minefield->field;
...
return minefield;
}