1

2 次元配列を渡すときに、列を指定する必要があります。例えば:

void funtion1(a[])// works
{
}
void function2(a[][4])//works
{
}
void function3(a[][])//doesn't work
{
}

function3が正しくない定義と見なされる理由として考えられるものは何ですか。function3行と列の両方を空白のままにしておくことができるように定義する別の方法はありますか? x[n]いくつかの返信を読んで:とがどのように違うのか説明できますかx[]?. 前者は特定の配列位置を表し、後者は未指定の配列だと思います。より多くの説明をいただければ幸いです。

4

4 に答える 4

2

2次元を指定せずに2D配列を渡すことはできません。そうしないと、パラメーター "a"がポインターに減衰するため、コンパイラーは2次元がオフセットを計算する時間を知る必要があります(2D配列が1Dとして格納される理由メモリ内)。したがって、コンパイラーは* aのサイズを認識している必要があります。これには、2番目の次元を指定する必要があります。ベクトルのベクトルを使用して、2D配列を置き換えることができます。

于 2013-03-15T14:40:14.850 に答える
1

これによりvoid function2(a[][4])、各行に 4 つの要素があることがわかります。void function3(a[][])わからないので、どこにあるべきかを計算できませんa[i]
c++ であるため、ベクトルを使用します。

于 2013-03-15T14:42:27.563 に答える
1

C スタイルの配列は、あなたが思うようには機能しません。それらをメモリのブロックと考えてください。次元は、元のアドレスからどれだけオフセットするかをコンパイラに伝えます。

int a[]は基本的にポインタであり、すべての要素は int です。つまり、a[1] は と同等です*(a + 1)。ここで、各 1 は sizeof(int) バイトです。a配列の制限や終わり (単純に言えば) はありません。[999999] を使用できますが、コンパイラは気にしません。

int a[][4]は似ていますが、コンパイラは各行が 4*sizeof(int) であることを認識するようになりました。したがって、[2][1] は*(a + 2*4 + 1)

int a[][]一方、 は不完全な型なので、コンパイラにとって a[2][1] は*(a + 2*?? + 1)であり、誰が何を知っていますか?? 意味。

を使用しないでくださいint **a。つまり、ポインターの配列を意味します。これは、おそらく望ましくないものです。

一部の人が言っているように、STL では、代わりにベクトルを使用してください。かなり安全に使用できますstd::vector<std::vector<int> > a。[2][1] は引き続き取得できます。

その際は、代わりに参照を使用してくださいconst std::vector<std::vector<int> > &a。そうすれば、各関数呼び出しで配列全体をコピーすることはありません。

于 2013-03-15T15:16:28.830 に答える
0

コンパイラは a[x][y] のアドレスをどのように計算しますか? 簡単に:

address_of_a+(x*SECOND_SIZE+y)

あなたが望むことを今想像してください

[2][3]

コンパイラは次を計算する必要があります。

address_of_a+(2*SECOND_SIZE+3)

コンパイラが SECOND_SIZE を知らない場合、これをどのように計算できますか? あなたはそれを明示的に彼に与える必要があります。コードで a[2][1]、a[100][13] を使用しているため、コンパイラはこれらのオブジェクトのアドレスを計算する方法を知る必要があります。

ここでもっと見る

于 2013-03-15T15:17:29.497 に答える