2010-12-13 13 views
4

動的に構築された2D配列を渡す方法を解明しようとしています。 私は列の数を指定する必要があることを知っていますが、私の場合はユーザーの入力に依存します。動的にサイズの2D配列を関数に渡す

回避策はありますか?

例:

// Some function 
void function(matrix[i][j]) { 
// do stuff 
} 
// Main function 
int N; 
cout << "Size: "; 
cin >> N; 

int matrix[N][N]; 

for (int i=0;i<N;i++) { // 
for (int j=0;j<N;j++) { 
    cin >> matrix[N][N]; 
} 
} 

sort(matrix); 

あなたがアイデアを得る:)

+0

前に議論されて。 http://stackoverflow.com/search?q=c%2B%2B+multidimensional+arrayから、私は[多次元配列をCとC++の関数に渡す方法]を見つけました(http://stackoverflow.com/questions/ 2828648 /多方向の配列 - 関数間のc-and-c)や他の多くの機能また、cで検索を行い、正しいが必ずしも間違っているとは限りません。 – dmckee

+0

6つの間違った答え、うわー! – UncleBens

+0

ねえ、なぜ6 ...? :) – Kos

答えて

4

あなたがC++を使っている場合は、合理的なオプションは以下のとおりです。

  • 使用boost::multi_array(推奨)、または
  • は、独自の2D配列クラスを作ります。まあ、そうする必要はありませんが、2D配列ロジックをクラスにカプセル化すると便利でコードをきれいにすることができます。どちらか、

    void func(int* arrayData, int arrayWidth) { 
        // element (x,y) is under arrayData[x + y*arrayWidth] 
    } 
    

    しかし、真剣にクラスでこれをラップまたはそのブーストは、すでにあなたのための準備ができて、そのクラスを持って楽しむ:

マニュアル2D配列のインデックスは次のようになります。これを手動で索引付けすることは面倒であり、コードをより不正確にし、エラーを起こしやすくします。


編集

http://gcc.gnu.org/onlinedocs/gcc/Variable-Length.htmlは、C99はあなたのためのもう一つの解決策を持っていることを言う:

void func(int len, int array[len][len]) { 
    // notice how the first parameter is used in the definition of second parameter 
} 

もC++コンパイラで動作するはずですが、私が今までにこのアプローチを使用していません。

+0

私はライブラリやクラスを使用することができないと思います。手動の方法を使用する必要があります。それでもエラーが発生しました: "void func(int *、int) 'に引数' 1'を 'int()[((unsigned int)((int)N))] 'から' int ** 'に変換できません。どのように渡す? (func(matrix、N);) – c4rrt3r

+1

@ c4rrt3r:func(&matrix [0] [0]、N); ' –

+1

' func(&matrix [0] [0]、N) 'はOKです。 (おっと、私は遅刻:)) – Kos

0

あなたは 空の機能を行うことができます(int型** __matrix、int32_t __row、int32_t __column) __row - 最大行 __column - 最大列。

アレイの制限を調べるには、これらのパラメータが必要です。

-3

無効機能(int型&行列[] [])

+0

コンパイルされません。 :)最高位の次元だけが未指定として残されます。 – Kos

+0

これはコンパイルされません。配列への参照ではなく、配列の参照を宣言しています。 –

0

はちょうどあなたの関数に別のparametrsを追加 - row_numbercolumn_numberを。 C++では配列はオブジェクトではないため、配列に関する追加情報は保存されません。

0

あなたが(ポインタへのポインタとして)配列識別子を渡す場合は、ポインタ演算を使用する必要があります:

void function(int** matrix, int num_rows, int num_cols) { 
    Assert(matrix!=NULL && *matrix!=NULL && num_rows>0 && num_cols>0); 

    for(int i=0; i<num_rows; i++) { 
     for(int j=0; j<num_cols; j++) { 
      // cannot index using [] like matrix[i][j] 
      // use pointer arithmetic instead like: 
      // *(matrix + i*num_cols + j) 

     } 
    } 
} 
+0

この場合も、不揃いの配列では機能しますが、int [] []型配列では機能しません。 – dmckee

+0

C/C++にプリミティブがないため、配列の限界外のメモリにアクセスできなくなります。私のコードは2D配列に対しても機能します。 –

+1

'int [x] [y]'を 'int **'として再解釈すると 'matrix [i] [j]'は何も役に立ちません。 Googleが '[]'演算子が何をして自分自身をチェックするかをGoogleに伝えます。 – Kos

1

コンパイラは、型の一部であるため、サイズを把握することができます。動的サイズの行列では機能しません。

template<size_t N, size_t M> 
void function(int (&matrix)[N][M]) 
{ 
    // do stuff 
} 

EDIT:GCCでのみ、配列を定義してコードのために必要である、あなたは直接可変長配列を渡すことができます。

void func(int N, int matrix[N][N]) 
{ 
    //do stuff 
} 

渡すthe gcc documentation

1
/*******************************************************\ 
*              * 
* I am not claiming to be an expert, but I think I know * 
* a solution to this one. Try using a Vector Container * 
* instead of an array. Here is an example below:  * 
*              * 
* Load the target file with a Multiplication Table  * 
*              * 
*              * 
\*******************************************************/ 

// reading a text file 
#include <iostream> 
#include <fstream> 
#include <string> 
#include <vector> 


std::string user_file; 
int user_size = 2; 
void array_maker(int user_size, std::string user_file); 

int main() { 
    std::cout << "Enter the name of the file for your data: "; 
    std::cin >> user_file; 
    std::cout << std::endl; 
    std::cout << "Enter the size for your Multiplication Table: "; 
    std::cin >> user_size; 

    // Create the users Multiplication data 
    array_maker(user_size, user_file); 

    return (0); 
} 

void array_maker(int user_size, std::string user_file) 
{ 
    // Open file to write data & add it to end of file 
    std::ofstream target_file(user_file,std::ios::out | std::ios::app); 

    // Declare the vector to use as a runtime sized array 
    std::vector<std::vector<int>> main_array; 

    // Initialize the size of the vector array 
    main_array.resize(user_size+1); // Outer Dimension 
    for (int i=0; i <= user_size; ++i) // Inner Dimension 
    { 
    main_array[i].resize(user_size+1); 
    } 

    for (int i=0; i<=user_size; ++i) 
    { 
    for (int j=0; j<=user_size; ++j) 
    { 
     main_array[i][j] = i * j; 
     // output line to current record in file 
     target_file << i << "*" 
       << j << "=" 
       << main_array[i][j] << " " 
       << "EOR" // End of Record 
       << std::endl; 

    } // Close Inner For 
    } // Close Outer For 
    // close file 
    target_file.close(); 

} // Close array_maker function 
+1

さて、ベクトルのベクトルは、パフォーマンスクリティカルなコードで2d行列を実装する恐ろしい方法です。メモリの読み取りとキャッシュのパフォーマンスはすべて地獄に行きます。 –

0

を参照してください。コンパイラが各フィールドの深さを知る必要があるため、1つの解決策は、テンプレートと呼び出しメソッドを通常の方法で使用し、コンパイラが各fieのサイズを推測することですld。

template <size_t m> 
void method(int M[][m]) 
{ 
    for(int i=0; i<m; ++i) 
     for(int j=0; j<m; ++j) 
     { 
      // do funny stuff with M[i][j] 
     } 
} 

int main() 
{ 
    int M[5][5] = { {1,0,1,1,0}, {0,1,1,1,0}, {1,1,1,1,1}, {1,0,1,1,1}, {1,1,1,1,1} }; 
    method(M); 
    // also you can call with method<5>(M) 
    // if you have different sizes for each dimension try passing them in args 
    return 0; 
} 
-1
int r, c 
int *matrix = new int[r,c]; 
for (int i = 0; i < r; i++) 
    { 
     /*cout << "Enter data" << endl;*/ 
     for (int j = 0; j < c; j++) 
     { 
      cin >> matrix[i,j]; 

     } 
    } 
+0

あなたはその質問を読んだことがありますか? – cpburnz

関連する問題