将指针传递给具有定义大小的 3D 数组
Passing a pointer to a 3D array with a defined size
我正在创建一个简单的游戏,其中有一个棋盘,我将其传递给许多函数以更改其值。现在我就是这样做的:
void play(int board[2][HEIGHT][WIDTH]);
其中 HEIGHT 和 WIDTH 均使用 define
定义。
我如何(应该)简化它?我在某处读到,像这样简化它并不是一个好方法:void play(int*** board)
,尽管我传递的内容总是具有完全相同的大小。
您可以将电路板放在结构中,然后使用这样的结构数组
struct Board {
int width;
int height;
int **data;
};
然后你可以写一个函数来初始化它,像这样
Board *new_board(int width, int height)
{
struct Board *board;
int i;
board = malloc(sizeof(struct Board));
if (board == NULL)
return NULL;
board->data = malloc(width * sizeof(int *));
if (board->data == NULL)
{
free(board);
return NULL;
}
board->width = width;
for (i = 0 ; i < width ; i++)
{
board->data[i] = malloc(height * sizeof(int));
if (board->data[i] == NULL)
{
while (--i > 0)
free(board->data[i]);
free(board->data);
free(board);
return NULL;
}
}
board->height = height;
return board;
}
然后你可以将 struct Board *pointer[2]
传递给你想要访问板的函数,并像这样初始化数组1
struct Board *pointer[2];
int i;
for (i = 0 ; i < sizeof(poitner) / sizeof(pointer[0]) ; ++i)
pinter[i] = new_board(width, height);
别忘了您还需要一个 free_board()
函数。
1假设您知道 width
和 height
.
在函数参数中,您可以省略多维数组第一维的长度。因此
void play(int board[2][HEIGHT][WIDTH]);
等同于
void play(int board[][HEIGHT][WIDTH]);
您还应该知道编译器会更改
void foo(int arr[]);
到
void foo(int *arr);
即arr
实际上是指向传递的数组的第一个元素的指针。请注意,传递的数组元素的类型为 int
.
现在考虑你的情况,传递的数组元素是 int [HEIGHT][WIDTH]
类型,即二维数组。因此,board
将成为指向 int [HEIGHT][WIDTH]
类型的二维数组的指针。
void play(int (*board)[HEIGHT][WIDTH]);
函数调用会像这样
play(board);
I read somewhere that it is not a good approach to simplify it like that: void play(int*** board)
, though what I am passing will always have exactly the same size.
是的。这是真的。那是因为 int ***
和 int (*)[HEIGHT][WIDTH]
是不同的类型,这意味着它们类型不兼容。
这样的事情会更简单吗?如果您想 撤消 最后一步,您也可以在 struct
中包含其他数据,例如分数。
#include <stdio.h>
#define HEIGHT 8
#define WIDTH 8
typedef struct Btype {
int board [HEIGHT][WIDTH];
} btype;
void play(btype *current) {
}
int main(void) {
btype history[2] = {0};
while (1) {
history[0] = history[1]; // save last state
play(&history[1]);
}
return 0;
}
我正在创建一个简单的游戏,其中有一个棋盘,我将其传递给许多函数以更改其值。现在我就是这样做的:
void play(int board[2][HEIGHT][WIDTH]);
其中 HEIGHT 和 WIDTH 均使用 define
定义。
我如何(应该)简化它?我在某处读到,像这样简化它并不是一个好方法:void play(int*** board)
,尽管我传递的内容总是具有完全相同的大小。
您可以将电路板放在结构中,然后使用这样的结构数组
struct Board {
int width;
int height;
int **data;
};
然后你可以写一个函数来初始化它,像这样
Board *new_board(int width, int height)
{
struct Board *board;
int i;
board = malloc(sizeof(struct Board));
if (board == NULL)
return NULL;
board->data = malloc(width * sizeof(int *));
if (board->data == NULL)
{
free(board);
return NULL;
}
board->width = width;
for (i = 0 ; i < width ; i++)
{
board->data[i] = malloc(height * sizeof(int));
if (board->data[i] == NULL)
{
while (--i > 0)
free(board->data[i]);
free(board->data);
free(board);
return NULL;
}
}
board->height = height;
return board;
}
然后你可以将 struct Board *pointer[2]
传递给你想要访问板的函数,并像这样初始化数组1
struct Board *pointer[2];
int i;
for (i = 0 ; i < sizeof(poitner) / sizeof(pointer[0]) ; ++i)
pinter[i] = new_board(width, height);
别忘了您还需要一个 free_board()
函数。
1假设您知道 width
和 height
.
在函数参数中,您可以省略多维数组第一维的长度。因此
void play(int board[2][HEIGHT][WIDTH]);
等同于
void play(int board[][HEIGHT][WIDTH]);
您还应该知道编译器会更改
void foo(int arr[]);
到
void foo(int *arr);
即arr
实际上是指向传递的数组的第一个元素的指针。请注意,传递的数组元素的类型为 int
.
现在考虑你的情况,传递的数组元素是 int [HEIGHT][WIDTH]
类型,即二维数组。因此,board
将成为指向 int [HEIGHT][WIDTH]
类型的二维数组的指针。
void play(int (*board)[HEIGHT][WIDTH]);
函数调用会像这样
play(board);
I read somewhere that it is not a good approach to simplify it like that:
void play(int*** board)
, though what I am passing will always have exactly the same size.
是的。这是真的。那是因为 int ***
和 int (*)[HEIGHT][WIDTH]
是不同的类型,这意味着它们类型不兼容。
这样的事情会更简单吗?如果您想 撤消 最后一步,您也可以在 struct
中包含其他数据,例如分数。
#include <stdio.h>
#define HEIGHT 8
#define WIDTH 8
typedef struct Btype {
int board [HEIGHT][WIDTH];
} btype;
void play(btype *current) {
}
int main(void) {
btype history[2] = {0};
while (1) {
history[0] = history[1]; // save last state
play(&history[1]);
}
return 0;
}