2

次のプログラムのコンパイル中にエラーが発生しました。なぜコンパイラがこのようなエラーを出すのか教えてもらえますか?

`#include <stdio.h>
void display(int **,int,int);
int main ()
{
int a[3][4]={1,2,3,4,5,6,7,8,9,0,1,6};
display(a,3,4);


return 0;
}
void display(int **a,int b,int c){

}

コンパイル中のエラー

 ` ptr.c: In function ‘main’:

  ptr.c:6:1: warning: passing argument 1 of ‘display’ from incompatible pointer type [enabled by default]
  ptr.c:2:6: note: expected ‘int **’ but argument is of type ‘int (*)[4]’ `
4

3 に答える 3

3

1D 配列はポインターに変換できますが (そしてすぐに変換されます)、2D 配列はポインターからポインターに変換されません。

問題は、関数内で、指定した 2D 座標に基づいてメモリ アドレスを計算するために、コンパイラが (少なくとも) 配列の幅を知る必要があることです。したがって、少なくとも 1 つのディメンションを明示的に指定する必要があります。より一般的には、N 次元配列が与えられた場合、最初の座標以外のすべての座標を指定する必要があります。

C++ を使用しているため、配列幅を内部に格納する a の周りに小さなラッパーを使用する方がほぼ確実に優れており、クリーンstd::vectorです。これにより、簡単に渡して操作できます。

template <class T>
class matrix { 
    size_t columns_;
    std::vector<T> data;
public:
    matrix(size_t columns, size_t rows) : columns_(columns), data(columns*rows) {}

    T &operator()(size_t column, size_t row) { return data[row*columns_+column]; }
};
于 2013-09-25T16:49:48.683 に答える
1

の最初の引数aは、コンパイラが言うように、互換性display()のある型int[3][4]であるため、に変換できない型です。int**

ただし、 にint[3][4]変換できint(*)[4]ます。したがって、display の最初のパラメーターを からint**aに変更するint (*a)[4]と、正常に動作します。

厳密に言えば、C (および C++) には 2 次元配列のようなものはありません a。これは、int[3][4]実際は配列の配列であるため、配列の最初の要素へのポインターに変換できます。最初の要素の型は , ですint[4]。したがって、最初の要素へのポインターint(*)[4]は になります。型の配列が(最初の要素へのポインタである) にint[100]変換できるように。int*

于 2013-09-25T16:51:04.553 に答える