1

2 次元配列 (行列)、列数、および行数を取得するプログラムを作成するように依頼されました。プログラムは転置行列を返します ([][] を使用せずに、ポインター演算のみを使用することを意味します)。

私が書いたプログラムは実際に行列を転置しますが、問題ありません。私の問題は、戻る方法を理解することです。ここに私のコードがあります:

int** transpose_matrix(matrix mat1,int number_of_rows,int number_of_columns)
{
    matrix mat2;
    int row_index,column_index;
    for(row_index=0;row_index<number_of_rows;row_index++)
    {
        for(column_index=0;column_index<number_of_columns;column_index++)
            **(mat2+(column_index*number_of_rows)+row_index)=**(mat1+(row_index*number_of_columns)+column_index);
    }
    // at this point, mat2 is exactly the transpose of mat1
    return mat2;
}

ここに私の問題があります:私は行列を返すことができません.私ができる最も近いことは、行列の最初の値のアドレスを返すことですが、たとえそうしても、残りの行列はすべて使用できなくなります. transpose_matrix 関数を終了して void main に戻ります...どうすれば mat2 を返すことができますか?

4

2 に答える 2

0

OK:ここに3つのことがあります:

  1. ローカル変数へのポインタを返すことはできません(戻った後はガベージになり、それが再利用されたスタック(メモリ)になります)。
  2. 渡されると、配列は最初の要素へのポインタに減衰します。
  3. ポインタ演算:p + 1はpのアドレスをsizeof(* p)だけインクリメントするため、pは次のバイトではなく次の要素を指します。

コードの簡単な修正(これは任意の行列サイズで機能します):

    int* transpose_matrix(int *mat1,int number_of_rows,int number_of_columns)
    {
        int *mat2=malloc(number_of_rows*number_of_columns*sizeof(int));
        int row_index,column_index;
        for(row_index=0;row_index<number_of_rows;row_index++)
        {
            for(column_index=0;column_index<number_of_columns;column_index++)
                mat2[column_index*number_of_rows+row_index]=mat1[row_index*number_of_columns+column_index];
        }
        // at this point, mat2 is exactly the transpose of mat1
        return mat2;
    }

...
    print(m,r,c); // I hope you have a print()
    int *t=transpose_matrix(m,r,c);
    print (t,c,r);
...
    // use t[max: c-1][max: r-1]
    free(t);

固定サイズの行列しかない場合(C99では可変長配列も使用できます!)。

typedef int  Matrix[ROWS][COLUMNS];
typedef int TMatrix[COLUMNS][ROWS];
typedef int (*pMatrix)[COLUMNS]; 
typedef int (*pTMatrix)[ROWS];  

pTMatrix transpose_matrix(Matrix m , int rows, int cols)
{
    pTMatrix t = malloc(sizeof(*t)*cols);
    for (int r=0; r<rows ; ++r)
    for (int c=0; r<cols ; ++r)
      t[c][r]=m[r][c];
    return t;
}

ええと、行と列が修正されている場合は、それを渡す必要はありません....うーん...

于 2013-03-19T21:10:05.907 に答える
0

1 つ目は、2 次元配列はdouble ポインターではありません。

2 つ目は、動的割り当てです。matrixが 2 次元配列型の場合、次のように記述します。

typedef int matrix[ROWS][COLUMNS];
typedef int (*matrix_ptr)[COLUMNS];

matrix_ptr transpose_matrix(matrix m, int rows, int cols)
{
    matrix_ptr transposed = malloc(sizeof(*transposed) * rows);
    // transpose, then
    return transposed;
}
于 2013-03-19T20:40:51.410 に答える