C 将指针传递到具有定义大小的三维数组
我正在创建一个简单的游戏,其中我有一个棋盘,我将其传递给许多函数以更改其值。现在我是这样做的:C 将指针传递到具有定义大小的三维数组,c,arrays,pointers,3d,C,Arrays,Pointers,3d,我正在创建一个简单的游戏,其中我有一个棋盘,我将其传递给许多函数以更改其值。现在我是这样做的: void play(int board[2][HEIGHT][WIDTH]); 其中,高度和宽度都是使用定义定义的 我该如何简化它?我在某个地方读到这样简化它不是一个好方法:void play(int***board),尽管我要传递的内容总是具有完全相同的大小。你可以将board放在一个结构中,然后使用这样的结构数组 struct Board { int width; int
void play(int board[2][HEIGHT][WIDTH]);
其中,高度和宽度都是使用定义定义的
我该如何简化它?我在某个地方读到这样简化它不是一个好方法:void play(int***board)
,尽管我要传递的内容总是具有完全相同的大小。你可以将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 {
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;
}
别忘了,您还需要一个免费板()
功能
1假设您知道函数参数中的宽度和高度,则可以省略多维数组第一维度的长度。所以
void play(int board[2][HEIGHT][WIDTH]);
相当于
void play(int board[][HEIGHT][WIDTH]);
您还应该知道编译器会发生更改
void foo(int arr[]);
到
i、 e.arr
实际上是指向所传递数组的第一个元素的指针。请注意,传递的数组元素的类型为int
现在考虑您的情况,传递的数组元素的类型为int[HEIGHT][WIDTH]
,即2D数组。因此,board
将成为指向int[HEIGHT][WIDTH]
类型的2D数组的指针
void play(int (*board)[HEIGHT][WIDTH]);
函数调用是这样的
play(board);
我在某个地方读到这样简化它不是一个好方法:void play(int***board)
,尽管我要传递的内容始终具有完全相同的大小
对。这是真的。这是因为int***
和int(*)[高度][宽度]
的类型不同,这意味着它们的类型不兼容 像这样的事情会更简单吗?如果希望撤消上次移动,也可以在结构中包括其他数据,例如分数
#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;
}
#包括
#定义高度8
#定义宽度8
类型定义结构B类型{
内板[高度][宽度];
}b型;
无效播放(B类型*当前){
}
内部主(空){
b类型历史记录[2]={0};
而(1){
历史记录[0]=历史记录[1];//保存上次状态
游戏和历史[1];
}
返回0;
}
这不仅不是一个好方法,也不会起作用。你所拥有的是正确的(尽管2
毫无意义)。无论你读到什么,使用int**
都不是一个“好主意”,也没有足够的描述性int(*)[HEIGHT][WIDTH]
和int***
是不兼容的类型,因此在“不是一个好主意”中应改为“根本不起作用”。@WhozCraig谢谢,改为传递地址,因为按值传递结构
无论如何都不会在函数调用后继续。保存副本的原因,只是猜测为什么有两块板,并利用它们。