まず、このポインターの定義
int array[10];
int **pointer = &array;
無効です。宣言の右側には type を持つ式がint ( * )[10]
あり、左側には type の識別子がありint **
ます。int ( * )[10]
ポインタとの間に暗黙的な変換はありませんint **
。そのため、コンパイラは診断メッセージを発行します。
正しい定義は次のようになります
int array[10];
int ( *pointer )[10] = &array;
ここで、これら2つの定義の違いは何かを検討できます
int array[10];
int *pointer = array;
と
int array[10];
int ( *pointer )[10] = &array;
最初のケースでは、ポインターが指すオブジェクトのサイズは にpointer
等しくなりsizeof( int )
ます。したがって、ポインター演算を使用する場合、式の評価後にポインターの値がバイト単位++pointer
で増加します。sizeof( int )
たとえばsizeof( int )
が に等しい場合4
、ポインタの値は だけ増加し4
ます。
2 番目の場合、ポインタpointer
が指すオブジェクトのサイズは に等しく、 が 4 に等しい10 * sizeof( int )
場合、オブジェクトのサイズは に等しくなります。したがって、ポインタが増加すると、その値は だけ増加します。sizeof( int )
40
++pointer
40
また、最初のケースでポインターを逆参照すると、型int
のオブジェクトが得られ、2 番目のケースでポインターを逆参照するint[10]
と、配列である型のオブジェクトが得られます。
また、配列はポインターではありません。単純に、それらは通常、式の最初の要素へのポインターに変換されます。C標準から
3 sizeof 演算子または単項 & 演算子のオペランドである場合、または配列の初期化に使用される文字列リテラルである場合を除き、''array of type'' 型の式は ''pointer 型の式に変換されます。配列オブジェクトの最初の要素を指し、左辺値ではない type'' へ。配列オブジェクトにレジスタ ストレージ クラスがある場合、動作は未定義です。
たとえば、
int array[10];
int *pointer = array;
thensizeof( array )
は等しくありませsizeof( pointer )
んが、一般的な構文を使用して配列の要素にアクセスできます。
array[ i ]
そしてpointer[ i ]
、同じ結果が得られます..