C++ポインタと配列:関係性をマスターする
C++ポインタと配列
このチュートリアルでは、配列とポインタの関係を実践的な例を通じて学びます。
C++において、ポインタは他の変数のアドレスを保持する変数です。ポインタは単一変数のアドレスだけでなく、配列の各要素のアドレスも格納できます。
以下の例を考えてみましょう:
int *ptr;
int arr[5];
// arrの最初の要素のアドレスをptrに格納
ptr = arr;
ここで、ptrはポインタ変数、arrはint配列です。ptr = arr;というコードは、配列の最初の要素のアドレスを変数ptrに格納します。
&arr[0]ではなくarrを使っていることに注目してください。これは両者が同じだからです。以下のコードも上記と同等です:
int *ptr;
int arr[5];
ptr = &arr[0];
残りの配列要素のアドレスは&arr[1]、&arr[2]、&arr[3]、&arr[4]で与えられます。
全配列要素を指す
同じポインタptrを使って配列の4番目の要素を指したいとします。
上記の例でptrが最初の要素を指しているなら、ptr + 3は4番目の要素を指します。例えば:
int *ptr;
int arr[5];
ptr = arr;
ptr + 1 は &arr[1] と等価
ptr + 2 は &arr[2] と等価
ptr + 3 は &arr[3] と等価
ptr + 4 は &arr[4] と等価
同様に、単一のポインタで要素にアクセスできます:
// 間接参照演算子を使用
*ptr == arr[0];
*(ptr + 1) は arr[1] と等価
*(ptr + 2) は arr[2] と等価
*(ptr + 3) は arr[3] と等価
*(ptr + 4) は arr[4] と等価
もしptr = &arr[2];で初期化した場合:
ptr - 2 は &arr[0] と等価
ptr - 1 は &arr[1] と等価
ptr + 1 は &arr[3] と等価
ptr + 2 は &arr[4] と等価

注意: ptrとptr + 1のアドレス差は4バイトです。これはptrがintデータへのポインタだからです。64ビットOSではintのサイズは4バイトです。
同様に、ポインタptrがchar型データを指す場合、ptrとptr + 1のアドレス差は1バイトです。文字のサイズは1バイトだからです。
例1: C++ポインタと配列
// 配列の各要素のアドレスを表示するC++プログラム
#include <iostream>
using namespace std;
int main() {
float arr[3];
// ポインタ変数を宣言
float *ptr;
cout << "配列を使ったアドレス表示: " << endl;
// forループで全配列要素のアドレスを表示
for (int i = 0; i < 3; ++i) {
cout << "&arr[" << i << "] = " << &arr[i] << endl;
}
// ptr = &arr[0]
ptr = arr;
cout << "\nポインタを使ったアドレス表示: " << endl;
// ポインタ記法で全配列要素のアドレスを表示
for (int i = 0; i < 3; ++i) {
cout << "ptr + " << i << " = " << ptr + i << endl;
}
return 0;
}
出力
配列を使ったアドレス表示: &arr[0] = 0x61fef0 &arr[1] = 0x61fef4 &arr[2] = 0x61fef8 ポインタを使ったアドレス表示: ptr + 0 = 0x61fef0 ptr + 1 = 0x61fef4 ptr + 2 = 0x61fef8
上記プログラムでは、まずポインタ変数ptrを使わずに配列要素のアドレスを単純に表示しました。
その後、ポインタptrを使ってa[0]のアドレスを指し、ptr + 1でa[1]のアドレスを指す、というようにしました。
ほとんどの文脈では、配列名はポインタに変換されます。簡単に言うと、配列名はポインタに変換されるのです。それがポインタを使って配列要素にアクセスできる理由です。
しかし、ポインタと配列は同じものではないことを覚えておくべきです。
配列名がポインタに変換されないケースがいくつかあります。詳細は「配列名がポインタに変換されない場合」を参照してください。
例2: 配列名をポインタとして使用
// ポインタ記法でデータを入力・表示するC++プログラム
#include <iostream>
using namespace std;
int main() {
float arr[5];
// ポインタ記法でデータ入力
cout << "5つの数字を入力: ";
for (int i = 0; i < 5; ++i) {
// 入力された数をarr[i]に格納
cin >> *(arr + i);
}
// ポインタ記法でデータ表示
cout << "データ表示: " << endl;
for (int i = 0; i < 5; ++i) {
// arr[i]の値を表示
cout << *(arr + i) << endl;
}
return 0;
}
出力
5つの数字を入力: 2.5 3.5 4.5 5 2 データ表示: 2.5 3.5 4.5 5 2
ここで、
-
まずポインタ記法を使って、ユーザーが入力した数を配列arrに格納しました。
cin >> *(arr + i);このコードは以下と等価です:
cin >> arr[i];別途ポインタ変数を宣言せず、配列名arrをポインタ記法で使っていることに注目してください。
既知の通り、配列名arrは配列の最初の要素を指します。したがって、arrをポインタのように振る舞わせることができます。
-
同様に、
forループでarrの値をポインタ記法で表示しました。cout << *(arr + i) << endl;このコードは以下と等価です:
cout << arr[i] << endl;
C言語
- C++構造体とクラス:組み込み開発者のための実践ガイド
- C++変数・リテラル・定数完全ガイド:基礎から実践まで
- C++クラスとオブジェクト完全ガイド:オブジェクト指向プログラミングの実践
- C++メモリ管理の極意:newとdeleteのエキスパート活用法
- C++ public/protected/private継承の違いを徹底解説
- C++フレンド関数とフレンドクラス:アクセス制御のマスター
- C言語ポインタ完全マスター: 実践的エキスパートガイド
- C言語における配列とポインタの関係を理解する
- C言語: アドレスとポインタを関数に渡す – 実践ガイド
- C言語 構造体とポインタ: 実践ガイド
- C++配列を徹底解説:宣言、初期化、ポインタ活用テクニック