第11回 配列とポインタについて
はじめに
前回は、変数のアドレスを扱うためのポインタについて学びました。
ポインタを使用すると、変数が保存されている場所を取得したり、その場所に保存されている値を操作したりできます。
一方、第7回では複数のデータをまとめて管理する配列について学びました。
配列とポインタは一見すると別々の機能に見えます。
しかし、C++ではこの2つには深い関係があります。
今回は、配列とポインタがどのように関係しているのかを学びます。
今回の到達目標
- 配列とポインタの関係を理解する。
- 配列の先頭アドレスを取得できる。
- ポインタを使用して配列の要素へアクセスできる。
- 関数へ配列を渡す方法を理解する。
配列とメモリ
まず、配列がどのように管理されているのかを考えてみましょう。
例えば、次の配列があります。
int data[3] = {10, 20, 30};
この配列は、複数の値を順番に管理しています。
イメージとしては、次のようになります。
data
┌────┬────┬────┐
│ 10 │ 20 │ 30 │
└────┴────┴────┘
↑
data[0]
配列の要素は順番に並んで管理されています。
そのため、配列には「最初の要素がどこにあるか」という情報があります。
配列名とアドレス
配列名を表示すると、配列の先頭要素のアドレスとして扱われます。
例えば、
int data[3] = {10, 20, 30};
の場合、
data
は、配列の先頭要素である
data[0]
の場所を表します。
そのため、
int* ptr = data;
と書くことができます。
これは、
int* ptr = &data[0];
と同じように、配列の先頭要素のアドレスをポインタに保存しています。
ポインタを使って配列の要素へアクセスする
ポインタを使用すると、配列の要素へアクセスできます。
例を見てみましょう。
#include <iostream>
int main()
{
int data[3] = {10, 20, 30};
int* ptr = data;
std::cout << *ptr << std::endl;
}
実行結果
10
ptrはdata[0]の場所を指しているため、
*ptr
で10を取り出すことができます。
ポインタを移動する
ポインタは、次の要素へ移動することができます。
例えば、
ptr + 1
と書くと、次の要素を指します。
ptr
↓
┌────┬────┬────┐
│ 10 │ 20 │ 30 │
└────┴────┴────┘
↑
ptr + 1
そのため、
std::cout << *(ptr + 1);
とすると、
20
が表示されます。
このように、ポインタを利用して配列の各要素へアクセスできます。
配列アクセスとポインタ
実は、配列の添字によるアクセスはポインタを使った書き方と関係があります。
例えば、
data[1]
は、
*(data + 1)
と同じ意味になります。
つまり、
data[0]
data[1]
data[2]
という書き方は、内部的にはポインタを利用したアクセスとして扱われています。
ただし、普段のプログラムでは配列の添字を使う方が分かりやすいため、基本的には
data[1]
のような書き方を使用します。
関数に配列を渡す
関数へ配列を渡すこともできます。
例えば、配列の中身を表示する関数を作成します。
#include <iostream>
void printArray(int data[], int size)
{
for (int i = 0; i < size; i++)
{
std::cout << data[i] << std::endl;
}
}
int main()
{
int numbers[5] = {1, 2, 3, 4, 5};
printArray(numbers, 5);
}
実行結果
1
2
3
4
5
このように、配列を関数へ渡すことで、配列を処理する関数を作成できます。
配列の要素数を渡す理由
先ほどの関数では、
void printArray(int data[], int size)
のように、配列とは別に
size
という値を渡しています。
これは、関数側では配列が何個の要素を持っているか自動では分からないためです。
そのため、
printArray(numbers, 5);
のように、要素数も一緒に渡します。
配列とポインタの違い
ここで重要なのは、
配列とポインタは同じものではない
ということです。
それぞれの役割は異なります。
種類
役割
配列
複数のデータをまとめて管理する仕組み
ポインタ
アドレスを保存する変数
ただし、配列は多くの場合、先頭要素のアドレスとして扱われるため、ポインタと組み合わせて利用できます。
まとめ
今回は、配列とポインタの関係について学びました。
- 配列の要素は順番に管理されています。
- 配列名は、多くの場合、先頭要素のアドレスとして扱われます。
- ポインタを使用して配列の要素へアクセスできます。
data[i]と*(data + i)は同じ意味になります。- 関数へ配列を渡す場合は、要素数も一緒に渡すことが一般的です。
- 配列とポインタは関係が深いですが、同じものではありません。
これで、C++における配列とポインタの基本的な関係を理解できました。
次回は、複数の異なる種類のデータをまとめて管理するための構造体について学びます。