何ができるのですか...関数に行列を渡す必要がありますか?行列を関数に渡す問題
error C2664: 'WriteMatrixOut' : cannot convert parameter 1 from 'char [480][640]' to 'char ** '
指摘されるタイプは無関係です。変換は
class Image
{
public:
char mm[480][640];
void WriteMatrixOut(char **mm);
}
何ができるのですか...関数に行列を渡す必要がありますか?行列を関数に渡す問題
error C2664: 'WriteMatrixOut' : cannot convert parameter 1 from 'char [480][640]' to 'char ** '
指摘されるタイプは無関係です。変換は
class Image
{
public:
char mm[480][640];
void WriteMatrixOut(char **mm);
}
ではなくvoid WriteMatrixOut(char mm[480][640]);
としてそれを宣言しreinterpret_castは、Cスタイルキャストまたは関数スタイルのキャストが必要です。
char**
とchar[x][y]
は基本的に異なり、キャストできません。
char array[100][100]
を実行すると、コンパイラはすべてのポインタを1つの場所に割り当てます。それはあまりにも同等です:
typedef char innerArray[100]; innerArray mm[100];
だから、100文字ごとの100のチャンクです。 sizeof(mm)
は10,000バイトになり、char*
にはキャストmmがchar**
より優れています。
しかし、char**
を使用して配列の配列を動的に割り当てると、ポインタの連続した配列へのポインタが1つあります。これらのポインタは、それぞれ任意の長さを有するメモリ内の任意の位置を参照する。 (これはまた、ギザギザの配列を持つことができます。)これらの2つのメモリレイアウトは、まったく異なっています。
は今、あなただけの引数宣言で同じ型を使用するように誘惑することができます
char mm[100][100];
void writeMatrixOut(char mm[100][100]);
しかし、Cは、問題がさらに混乱なるため、これは安全ではありません。 foo(int x[3])
,foo(int x[])
およびfoo(int *x)
はすべて同等です。私はネストされた配列でどのように動作するのかよく分かりませんが、少なくとも1つの配列次元は、引数を渡すときにコンパイラによってチェックされません。
あなたはtypedefのでこれを避けることができます。
typedef char Matrix[100][100];
Matrix mm;
void writeMatrixOut(Matrix &mm); // might even be 'const Matrix &'
それでも、あなたは配列を割り当てたり、返すことはできません。
struct Matrix { char elements[100][100]; }
Matrix mm;
void writeMatrixOut(Matrix &mm); // might even be 'const Matrix &'
C++ 03/C++ 11にもあなたのためにこれを行うことができ、アレイ<>ラッパークラスが含まれていますが、それは次のとおりです。配列は動作させるためには、構造体やクラスでそれらをラップする必要がありネストされた配列で扱いにくい:
// namespace std::tr1:: in C++03, std:: in C++11
typedef array<100, array<100, char>> Matrix;
このようなパラメータは、 'char [] [640]'のように宣言できます。 – Yappie
Yappieのコメントは、これがなぜこの引数を宣言するための型安全な方法ではないのかを示しています。型安全性をもっと必要とするならば、 'void WriteMatrixOut(char(&mm)[480] [640]); 'を使うことができます。これは正確にこれらの次元を持つ配列への参照であり、コンパイラは関数を呼び出すとき。 –