web-dev-qa-db-ja.com

関数から行列(2D配列)を返す方法は? (C)

ビンゴボードを生成する関数を作成し、ビンゴボードを返したい。

期待していなかったように、機能しません。

ここに関数があります:

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」行にコンパイルエラー(赤いサブライン)があります。

2D配列を返す方法はありますか?without structs\dynamic allocationsを使用して?

Microsoft Visual C++ Express 2010を使用しています。

15
Billie

誰かがそのボードのメモリを所有する必要がありますsomewhere、そしてさらに重要なことに、その所有権はこの関数の呼び出し元にまでさかのぼる必要があります。ダイナミックアロケーションを使用しない場合、他の唯一の実際の選択肢は、in/outパラメーターとして関数に送信することです。

_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()呼び出しの再配置も検討します。理想的には、繰り返し呼び出し可能な可能性のある関数には決して含まれず、プロセスの実行ごとにonceのみが実行されることが保証されるべきです。 (注:thread実行ごとに1回かどうかは正直覚えていませんが、コーディングの学習曲線のこの時点では、複数のスレッド化はまだレーダーにありません)。

最後に、ランダムフィルループは不必要に繰り返されます。あなたが明らかにしようとしていることを生成するより良い選択肢があります:数字の既存のセットのランダムな順列を作成します。書かれているように、_MAX_RANGE_が_(N*M)_と比較してどれだけ大きいかに応じて、最後のいくつかのスロットを埋めようとしてしばらくスピンすることができます。

13
WhozCraig

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);
 }
17
Israel Unterman