1

以下の何が間違っていますか

int data[2][2] = { {1,1}, {2,2}};
int sum = sum(data, 2);

合計は次のように定義されます

int sum(int **data, int rows);

data には のアドレスが含まれているdata[0]ため、ポインターとして扱うことができます。これ*dataは type の別の配列ですint。この別の配列は、最初の要素へのポインタとして扱われるべきです。したがって、コンパイラは int の引数で文句を言うのはなぜ**dataですか?

以下に示すように、コンパイルエラーが発生します。私はエラーを理解していますが、私の質問は、なぜ**data受け入れられないのかということです.

error: cannot convert int (*)[2] to int** for argument 1 to int sum(int**, int)
4

6 に答える 6

3

配列が1次元であるか多次元であるかに関係なく、最初の要素へのポインターにのみ変換でき、ポインターの配列へのポインターには変換できません。

理由を理解するには、配列がメモリ内にどのように配置されているかを分析します。

int data[3]
0.......4.......8...... (assume sizeof(int)==4)
data[0] data[1] data[2]
^ &data[0]

int data[3][2]
0..........4..........8..........12.........16.........20........
data[0][0] data[0][1] data[1][0] data[1][1] data[2][0] data[2][1]
^ &data[0][0]

すべての要素は常に線形に配置されるため、すべての配列(1次元または多次元)は最初の要素(arr[0][0]...[0])へのポインターとして表現できます。多次元配列は、ポインターの配列がどこにも存在しないため、ポインターの配列へのポインターとして表すことはできません。

ディメンションは、アドレスに変換するためのコンパイル時のヒントにすぎません(arr[i][j]になります*(array_memory + i*H + j))。ポインタへのポインタは、配列とはまったく異なる構造です。索引付けは構文的には同じように見えますが、まったく異なることが起こります(ppi[i][j]になります) *(*(ppi + i) + j)

于 2012-05-22T13:33:58.177 に答える
2

パラメータの定義に配列のサイズを含めることになっています。

    int sum(int data[2][2], int rows);

注: 動的配列の場合は、前に行ったことは正しいです。

于 2012-05-22T13:27:50.570 に答える
1

これが役立つかもしれません:

int sum(int *i, int rows) {
    cout << *i << *(i+1) << *(i+2) << *(i+3);
    return 0;
}

int main() {
    int data[2][2] = { {1,1}, {2,2}};
    int sum1 = sum(data[0], 2);

    return 0;
}
于 2012-05-22T13:40:02.420 に答える
0

int ** dataへのポインタへのポインタintです。

sumsの最初の引数にデータを渡すことは、実際には単にaint*を渡すことであり、これは。と同じではありませんint **

さらに、に入ると、2次元配列sum()を指していることはわかりません。それは、それが...int **dataへのポインタへのポインタであることを知っているだけです。int

初めてデータを逆参照すると、へのポインタが得られますint。2回目にデータを逆参照すると、が得られますint

関数へのインターフェースを変更する必要がありますsum()

于 2012-05-22T13:33:48.153 に答える
0

int data [2][2]//基本的に4つの値の配列です。配列の配列ではありません。
dimentionalsは、値にアクセスする方法をコンパイラーに説明するだけです。

あなたが持っているとしましょう:

data[R][C]  
data[X][Y] == *(&data)[X*C + Y]  

この説明に従って、関数を定義する必要があります。

int sum(int *data, int rows);

そして、それが何をするのかを示したいのなら、私はあなたがそれを正しく使うのを手伝うかもしれません。

于 2012-05-22T13:33:59.257 に答える
0

配列名からポインターへの減衰は 1 回しか発生しないため、ポインターからポインターへではなく、ポインターを取得します。

AC/C++ 配列は、データ要素の連続した割り当てです。配列の配列は、依然として要素の連続した割り当てです。要素が大きくなっているだけです。これは、エラー メッセージ " cannot convert int (*)[2] to int**" が言っていることです。

別の見方をすると、二重逆参照は、ポインターの配列がどこかを指している場合にのみ機能します。ただし、C/C++ はこれを行いません。自分で割り当てて埋める必要があります。

タイプは、int (*)[2]配列の配列に としてアクセスできるようにするものですdata[i][j]。そのように配列にアクセスしたい場合は、その型が使用されているすべての場所にその型を伝播する必要があります。

于 2012-05-22T16:09:13.503 に答える