如何从函数中返回矩阵(二维数组)?(C语言)

16

我创建了一个生成bingo棋盘的函数,并希望返回该bingo棋盘。

由于没有预料到某些情况,该函数无法正常工作。

以下是该函数:

int** generateBoard() {
    int board[N][M], i, j , fillNum;
    Boolean exists = True;
    // initilize seed
    srand(time(NULL));
    // fill up..
    for(i = 0; i < N; ++i) {
        for(j = 0; j < M; ++j) {
            exists = True;
            while(exists) {
                fillNum = rand()%MAX_RANGE + 1; // limit up to MAX_RANGE
                if(beenAdded(board, fillNum) == Exist) {
                    continue;
                } else {
                    board[i][j] = fillNum;
                    exists = False;
                }
            }
        }
    }
    return board;
}

在"return board"这一行出现了编译错误(红色下划线)。

有没有一种方法可以在不使用结构体\动态分配内存的情况下返回一个二维数组?

我正在使用Microsoft Visual C++ Express 2010。


使用malloc函数为二维数组分配内存空间。 - Adeel Ahmed
我不能,这是作业...如果我能的话,我会做的。 - Billie
1
你最好了。现在你正在返回一个在退出函数作用域后不再有效的局部变量。这是未定义的行为。传入输出参数可以接受吗? - WhozCraig
不行,因为我们还没有学习指针(尽管我已经学了..)。无论如何,在函数中不需要这样做。我只是认为这样更清晰。 - Billie
将二维数组作为generateBoard函数的参数,函数签名如下: int generateBoard(int **board) - Adeel Ahmed
1
这个函数只被调用了一次吗?你学过 static 关键字了吗? - mpontillo
3个回答

21

您将board定义为局部变量 - 当函数超出其作用域时,它的内存将被释放。

您可以将board声明为全局变量,或者可以通过以下方式动态创建:

int **allocate_board(int Rows, int Cols)
{    
    // allocate Rows rows, each row is a pointer to int
    int **board = (int **)malloc(Rows * sizeof(int *)); 
    int row;

    // for each row allocate Cols ints
    for (row = 0; row < Rows; row++) {
        board[row] = (int *)malloc(Cols * sizeof(int));
    }

    return board;
}
你需要动态释放该板块:
// you must supply the number of rows
void free_board(int **board, int Rows) 
{
    int row;

    // first free each row
    for (row = 0; row < Rows; row++) {
         free(board[row]);
    }

    // Eventually free the memory of the pointers to the rows
    free(board);
 }

18

必须有某个地方拥有那个板子的内存,更重要的是,这种所有权必须延伸到该函数的调用者。没有动态分配,你唯一的其他选择是将其作为输入/输出参数发送到该函数中。

void generateBoard(size_t N, size_t M, int board[N][M])
{
    int i, j , fillNum;
    Boolean exists = True;
    // initilize seed
    srand(time(NULL));
    // fill up..
    for(i = 0; i < N; ++i) {
        for(j = 0; j < M; ++j) {
            exists = True;
            while(exists) {
                fillNum = rand()%MAX_RANGE + 1; // limit up to MAX_RANGE
                if(beenAdded(board, fillNum) == Exist) {
                    continue;
                } else {
                    board[i][j] = fillNum;
                    exists = False;
                }
            }
        }
    }
}

并从您的调用者中这样调用:

int main()
{
    const size_t N = 10;
    const size_t M = 10;
    int board[N][M];

    generateBoard(N,M,board);

    ...
}

我还建议将 srand() 调用迁移到 main() 中的启动代码中。它理想情况下不应该在一些可能重复调用的函数中,而且应该确保每个进程执行只执行一次。(注意:老实说,我无法记住它是否仅在每个线程执行一次,但在你的编码学习曲线上,我猜测多线程目前还不是你的重点)。

最后,你的循环填充随机数是不必要的重复操作。有更好的方法来生成你显然试图创建的东西:一个现有数字集合的随机排列。按照当前的写法,根据 MAX_RANGE 相对于 (N*M) 的大小关系,你可能需要花费一些时间才能填满这些最后几个插槽。


0
int **setMatrix(int *row1, int *cols1) //return matrix
{
    int row, cols;
    int **matrix;
    printf("enter row:\n");
    scanf("%d",&row);
    printf("enter cols:\n");
    scanf("%d",&cols);
    
    
    matrix=(int **)calloc(cols ,sizeof(int*));
      for(int i=0;i<cols ;i++)
      {
          matrix[i]=(int *)calloc(row ,sizeof(int));
      }
    *row1=row;
    *cols1=cols;
    return matrix;

    


}


int main()
{
   int row ,cols;
   int **matrix;

   matrix=setMatrix(&row, &cols); //get the matrix back 
    
   return 0;
 } 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接