6

int ポインターを宣言するいくつかの例に従っています

int *myInt;

次に、そのポインターを配列に変換します

myInt = (int*)malloc(1024);

これはチェックアウトします

myInt[0] = 5; 
cout << myInt[0]; // prints 5
myInt[1] = 7;
cout << myInt[1]; // prints 7

int ポインターは int へのポインターであり、それ以外のものではないと思いました。文字列へのポインターは文字列の最初の文字を指すだけであることは知っていますが、ここでは int の配列で同じようなことが起こっているようです。しかし、必要なのが int の配列である場合、int へのポインターの代わりに単に int の配列を作成しないのはなぜでしょうか?

ところで、これが C++ ではなく C でどのように機能するかに興味があります。これは C++ ファイルにありますが、関連するコードは C です。

4

5 に答える 5

12

int ポインターは int の配列ですか?

いいえ。

intポインターはintへのポインターであり、それ以外のものではないと思いました

それは正しい。ポインターはポインター、配列は配列です。

混乱を招くのは、ポインターが配列の最初の要素を指している可能性があり、配列が最初の要素へのポインターに崩壊する可能性があることです。さらに紛らわしいのは、ポインターの逆参照とポインター演算の構文が、配列がインデックス付けに使用する構文と同じであることです。すなわち、

ptr[i]

と同等です

*(ptr + i)

ifptrはポインタです。もちろん、同様に、配列arr[i]ith要素でもありarrます。類似性は、ポインターと配列の共通の性質から生じます。これらは両方とも、メモリ (潜在的にはブロック) に間接的にアクセスするために使用されます。

この強い関係の結果、状況によっては(およびいくつかの制約がある場合)、配列とポインターを交換可能であるかのように使用できます。これは、それらが同じであることを意味するわけではありませんが、十分な共通のプロパティを示しているため、それらの使用法はしばしば「同一」に見えます。

于 2013-06-21T17:09:03.847 に答える
3

ポインターが指すアイテムにアクセスするための代替構文、角括弧があります。この構文を使用すると、ポインターが配列であるかのように、ポインターを介してデータにアクセスできます (もちろん、ポインターは配列ではありません)。式a[i]は単に*(a+i)*の代替形式です。

動的ストレージを割り当てて に割り当てるとmyInt、実行時にサイズを変更できる動的配列のようにポインターを使用できます。

myInt = malloc(1024*sizeof(int)); // You do not need a cast in C, only in C++
for (int i = 0 ; i != 1024 ; i++) {
    myInt[i] = i; // Use square bracket syntax
}
for (int i = 0 ; i != 1024 ; i++) {
    printf("%d ", *(myInt+i)); // Use the equivalent pointer syntax
}


*ちなみに、可換性のは;の代わりに+書くことができます。それをしないでください!4[array]array[4]

于 2013-06-21T17:06:18.643 に答える
1

それらは同じではありません。ここに目に見える違いがあります。

int  array[10];
int  *pointer;

printf ("Size of array = %d\nSize of pointer = %d\n",
    sizeof (array), sizeof (pointer));

結果は、

Size of array = 40
Size of pointer = 4

"array + 1" を実行すると、結果のアドレスは array[0] + 40 のアドレスになります。 "pointer + 1" を実行すると、結果のアドレスは pointer[0] + 4 のアドレスになります。

配列宣言により、コンパイル時にメモリが割り当てられます。ポインタ宣言ではコンパイル時のメモリ割り当てが発生せず、calloc() または malloc() を使用した動的割り当てが必要です。

次の割り当てを行うと、実際には整数配列から整数ポインターへの暗黙的な型キャストです。

pointer = array; 
于 2013-06-22T03:14:19.537 に答える
1

int ポインターは int の配列ではありません。しかし、より大きな質問は、配列とポインターの両方が必要な理由のようです。

配列は、データのメモリ内の実際のストレージを表します。そのストレージが割り当てられると、配列表記を使用して格納されたデータを参照するか、ポインター表記を使用して格納されたデータを参照するかに大きな違いはありません。

ただし、このストレージは配列表記を使用せずに割り当てることもできます。つまり、配列は必ずしも必要ではありません。配列の主な利点は、メモリの小さなブロックの便利なint x[20]割り当てarray[i]です*(array+i)。ありがたいことに、このより便利な表記法はarray、配列宣言に由来するものであるか、単なるポインターであるかに関係なく使用できます。(基本的に、配列が割り当てられると、その時点以降の変数名は、配列の最初の値のメモリ内の場所を指すように割り当てられたポインターと同じです。)

配列に大きすぎるメモリ ブロックを直接割り当てようとすると、コンパイラがエラーを出すことに注意してください。

配列:

  • 割り当てられた実際のメモリを表す
  • 配列の変数名は、配列が始まるメモリ内のポイントを参照するポインターと同じです (変数名 + 1 は、配列の 2 番目の要素が始まるメモリ内のポイントを参照するポインターと同じです (存在する場合)など)
  • 配列内の値は、次のような配列表記を使用してアクセスできますarray[i]

ポインター:

  • 何かの場所を記憶に保存する場所
  • 配列に割り当てられたメモリを参照できます
  • または、次のような関数によって割り当てられたメモリを参照できますmalloc
  • ポインタが指すメモリに格納された値は、ポインタを逆参照することでアクセスできます*pointer
  • 配列の名前もポインタであるため、配列の最初の要素の値は でアクセスでき*array、2 番目の要素は *(array+1) などでアクセスできます。
  • 整数をポインタに加算または減算して、プログラムが割り当てたメモリの同じブロック内の他の値を指す新しいポインタを作成できます。たとえば、array+5 は、値 array[5] が格納されているメモリ内の場所を指します。
  • ポインタをインクリメントまたはデクリメントして、同じメモリ ブロックの他の値を指すことができます。

多くの場合、どちらか一方の記法の方が便利なので、両方の記法が利用可能であり、相互に簡単に交換できることは非常に有益です。

于 2013-06-21T17:48:40.753 に答える
1

一種の、そして技術的にはいいえ。int ポインターは int を指します。ただし、int の配列はメモリ内で連続しているため、次の int は を使用して参照できます*(myInt+1)。配列表記myInt[1]は、myInt ポインターを使用し、それに 1 単位 (int のサイズ) を追加し、その新しいアドレスを参照するという点で同等です。

したがって、一般的に、これは真実です:

myInt[i] == *(myint + i)

したがって、int ポインターを使用して配列にアクセスできます。'\0'キャラクターに気をつけて立ち止まるように注意してください。

于 2013-06-21T17:08:55.637 に答える