0

配列へのポインタの構文について質問があります。配列はそれ自体がポインターであることをよく知っています(私たちの大学教授が言ったこと)。なぜ別のポインター(ポインターへのポインター)でそれらを指すときに、次の構文を使用するのですか:

int array[10]; 
int *pointer = array;

この構文の代わりに:

int array[10];
int **pointer = &array;

これはmallocを使用して正しいことはわかっていますが、通常の方法ではないのはなぜですか?それはコンパイラまたは構文の問題ですか、それともどこかで間違っていますか??

4

3 に答える 3

5

間違っていることを教授に伝えてください。配列はポインターではありません。配列はポインターに分解できますが、ポインターでありません。

int* pointer = array;の最初の要素を指すポインターを宣言しますarray

int** pointer = &array;は正しくありません。コメントでjschultz410が述べたように、 の型は&arrayis not int**でありint (*)[10]、10 個の int の配列へのポインターであり、 に減衰することはできませんint**

于 2015-03-01T04:53:08.220 に答える
3

配列自体がポインターであることはわかっています

いいえ。配列はポインターではありません。配列は配列です。sizeofまたは 単項演算&子のオペランドである場合を除いて、型 "N 要素配列" のTは型 "pointer to T" の式に変換 ("decay") され、式の値は配列の最初の要素のアドレス。ただし、配列要素自体に加えて、ポインター用に確保されるストレージはありません。

したがって、宣言を考えると

int array[10];

式の型arrayは「10 要素配列int」です。がまたは 単項arrayのオペランドでない限り、型に崩壊します。そうsizeof&int *

int *ptr = array;

動作します。

の型は で&arrayはありません int **。タイプはint (*)[10]、または「の 10 要素配列へのポインタint」です。次のようなポインターを宣言して初期化します

int (*ptr)[10] = &array;
于 2015-03-01T05:19:08.860 に答える
3

まず、このポインターの定義

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++pointer40

また、最初のケースでポインターを逆参照すると、型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 ]、同じ結果が得られます..

于 2015-03-01T05:19:10.517 に答える