プログラミングC:ポインタを持つ配列

この記事はシリーズの一部です – どのようにプログラミングするには:Cプログラミング

序文

以前の記事では、ポインタと配列について説明しました。 各記事では一般的に個別に説明しましたが、Cプログラミング言語では配列とポインタは実際には共通してリンクされています。 これは、機能の各部分が同じことを見るための異なる方法を提供するためです。 この点で、同じ主題の視点としてポインタと配列を表示することができます。つまり、メモリ内の連続した要素です。 うまくいけば思い出して、Cで配列が宣言されると、連続したメモリが割り振られ、それに割り当てられます。 アレイに12個の要素がある場合、最後に続く12個のメモリのチャンクがセットアップされ、プログラム内に保存されます。 うまくいきなり思い出すと、ポインタをインクリメントすると、配列の基本型のサイズに等しいメモリ内の次の場所にアクセスします。 この2つの事実から、ポインタと配列がどのように関連しているかを見ることができます。

配列とポインタ

次のように10要素のint配列を指定したとしましょう:

インデックスのない配列の名前を指定するだけで、配列の最初の要素へのポインタを生成できます。

これは次のように書くことと同じです:

実際、どちらも有効なCプログラミングですが、実際には2番目の形式はほとんど見られません。 これは、書き込みが不気味で、より多くの文字が含まれるため、エラーの可能性が高くなるからです。

これは、配列の最初の要素へのポインタのように、インデックスなしで配列自体を考えることができるため可能です。 実際、索引付けの行為は、「場面の裏で」行われた実際のポインタ算術の省略形と考えることができます。 たとえば、myArray [3]にアクセスすると、一連のint値の3番目のint値にアクセスすることになります。 このようにして、配列の最初の要素へのポインタがあり、それに3を加えた場合(ポインタ算術)、myArray [3]を索引付けしたときと同じメモリのアドレスにアクセスします。 ポインターをインクリメントすると、その基本タイプを基準にした次のメモリーアドレスをポイントすることに注意してください。 これをより明確にするには、下の図を参照してください。

この例では、myArray [2]は*(myPtr + 2)と等価です。 ポインタは基本データ型(この場合はint)に対して相対的にインクリメントされることに注意してください。 したがって、myPtrに2を加えると、メモリ内の2つのintを指すようになります。同様に、myArray [2]にアクセスすると、配列の連続したメモリに格納されている3番目のintにアクセスします。 これらはメモリ内の同じ値にアクセスする2つの方法です。 実際にそれは奇妙になる…

上記のコードブロックで行ったように、配列の基本型のポインタを配列の最初の要素のアドレスに代入すれば、実際にはポインタ自体のようにインデックス機構を使用することができます 配列そのもの。 私はコードの一部がこれをさらに説明するかもしれないと思います:

上の図のように、インデックス機構(myArray [#])を*(myArrayPointer +#)の短縮形と考えることができます。

多次元配列は同じです。 Cは多次元配列を作成するとき、基本的に各行をメモリ内に次々に配置するので、行1の最後の要素は行2の最初の要素のすぐ隣にあります。 ポインタ演算を使用してこれらの配列にアクセスすることはできます。 省略形は、余分な次元に対応するために単純に少し成長します。

もちろん、より多くの次元を追加すると、それがより混乱し複雑になるので、2つの次元で停止します。

これのポイントは、配列は単純に一連の値の並びであり、メモリ内で順に並んでいるということです。 ポインタとその算術演算は同じように動作するので、ポインタに1を加えると、ポインタがメモリの基本型の次のアドレスにジャンプし、配列にアクセスする別の方法が提供されます。

ポインターの基本型としての配列

ポインタの基本型を実際に配列にすることは可能です。 この意味で、ポインタの基底型の長さが10の場合、ポインタをインクリメントするたびにメモリ内の10個先にジャンプします。 これは、ポインタ宣言の微妙な変更によって行われます。

これは多次元配列ポインタです。つまり、配列の各行をその基点とすることを意味します。 2次元配列をインデックスするのと同じようにインデックス可能です。 しかし、メモリ上の1つの文字のサイズをジャンプする代わりに、ポインタ演算を実行すると、メモリ内の10 charsのサイズにジャンプします。 10の後にさらにディメンションを追加して、配列内にさらに配列を作成することができます。 これはポインターのタイプで、多次元配列を扱うためのポインターを設定する方法の例です。

ここで重要な点は、このコードスニペットが示すとおり、ポインタを上記のように索引付けすると、正しく動作することです。

元の配列と同じ方法で多次元配列にアクセスするポインタを定義する方法を確認できます。 上記のようにまっすぐ1次元ポインタを使用して多次元配列にアクセスするか、ここに示すように多次元ポインタを使用するかを選択できます。

結論

ポインタと配列はCで密接に関連しています。配列の内容にアクセスするためのインデックスとポインタを使用することは、同じコインの単純な2つの側面です。 彼らは同じ目標を目指す2つの視点を提供しています。 ポインタ算術(ポインタの記事で説明しました)では、配列内の各要素に次々にまたはランダムにアクセスできます。 配列の索引付けを使用すると、理解しやすく読みやすい短い番号を指定できますが、同じことができます。 これは、配列が1つの連続するデータブロック内のメモリに配置されるため可能です。 ポインタ演算を使用して配列にアクセスすることは、多くのプロフェッショナルなCプログラムでは、パフォーマンスを向上させる方法として、またより一般的な方法でデータ構造を処理する方法としてよく使用されます。

注:Cコンパイラは、ポインタまたは配列インデックスが実際に有効かどうかをチェックしません。 これは、配列のサイズの外側でインデックスを作成したり、既存の配列の外側にポインタを移動したりする完全に有効なCプログラムです。 これにより、不明な動作が発生し、メモリ内のランダムな点から書き込みまたは読み取りが行われます。 これは悲惨な結果を引き起こすことがあります。 プログラマは、データを読み書きする前に、すべてのポインタと配列が適切なサイズに束縛されていることを確認する必要があります。

この記事はシリーズの一部です – どのようにプログラミングするには:Cプログラミング

この記事を読んでいただければ、パトリオンのサポートを検討することもできます。

しかし、毎月の約束が少しでもあれば、私はそれを得る、あなたは私にコーヒーを買うことを考えるかもしれない。

photo credit: Owen Signalman Lowestoft via photopin (license)

あわせて読みたい

コメントを残す

%d人のブロガーが「いいね」をつけました。