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谢谢,改为传递地址,因为按值传递
结构
无论如何都不会在函数调用后继续。保存副本的原因,只是猜测为什么有两块板,并利用它们。