2次元配列をC言語の2次元ポインタに変換できないのはなぜですか?

なぜ次のプログラムは 'conversion'を与えますか?int [1] [1]からint ** エラーに変換できませんか?私はVS2008でWindows 7の下でコンパイルしています。

int main(){
    int a[1][1] = {0};
    int **p = a;
}
2
配列はポインタではありません。 配列はポインタではありません
追加された 著者 Adam Rosenfield,

2 答え

配列をポインタに変換できるのは1回だけです。 "ポインタ==配列"抽象化は、第2レベル以降を中断します。

できるよ

int (*p)[1] = a; //convert an array of arrays of length 1
                //to a pointer to arrays of length 1

しかし、それぞれの場合にメモリレイアウトがわかると、多目的配列をポインタへのポインタに変換できないことは明らかです。

//multidimentional arrays (a[][])
a -> [first row][second row][...]

//pointers to pointers (**p)
p -> [p0][p1][p2]
      |    |   |
      |    |   \-> [third row]
      |    \-----> [second row]
      \----------> [first row]

ポインタからポインタへのアプローチでは、行は必ずしも連続しているわけではなく、個々の行を指し示す余分な配列が必要です。

6
追加された
本当にしたいが、行へのポインタを格納するために追加の配列を取り除く方法がない場合は、2番目のケースからデータを連続的に割り当てることができます
追加された 著者 hugomg,
私はアレイは常に連続していると思った..?
追加された 著者 nikel,

a is an array of an array of ints, so it can decay to a pointer to the first element, which is an array of ints. So you need to declare the pointer as follows:

int (*p)[1] = a;

もっと抽象的に言えば、配列 T a [N]; がある場合、 a T * にまで崩壊します。あなたの状況では、 T = int [M] T * = int(*)[M] のようになります。

4
追加された
これは、実際には、私が int * [M] にキャストしようとしたときに、もっと便利な説明でした(行へのポインタの代わりにポインタの行になりました)。 contiguityの問題は、演算子の優先順位とは異なり、直感的です。
追加された 著者 bug,