工業製造
産業用モノのインターネット | 工業材料 | 機器のメンテナンスと修理 | 産業プログラミング |
home  MfgRobots >> 工業製造 >  >> Industrial programming >> C言語

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] と等価
C++ポインタと配列:関係性をマスターする

注意: 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

ここで、

  1. まずポインタ記法を使って、ユーザーが入力した数を配列arrに格納しました。

    cin >> *(arr + i);

    このコードは以下と等価です:

    cin >> arr[i];

    別途ポインタ変数を宣言せず、配列名arrをポインタ記法で使っていることに注目してください。

    既知の通り、配列名arrは配列の最初の要素を指します。したがって、arrをポインタのように振る舞わせることができます。

  2. 同様に、forループでarrの値をポインタ記法で表示しました。

    cout << *(arr + i) << endl;

    このコードは以下と等価です:

    cout << arr[i] << endl;

C言語

  1. C++構造体とクラス:組み込み開発者のための実践ガイド
  2. C++変数・リテラル・定数完全ガイド:基礎から実践まで
  3. C++クラスとオブジェクト完全ガイド:オブジェクト指向プログラミングの実践
  4. C++メモリ管理の極意:newとdeleteのエキスパート活用法
  5. C++ public/protected/private継承の違いを徹底解説
  6. C++フレンド関数とフレンドクラス:アクセス制御のマスター
  7. C言語ポインタ完全マスター: 実践的エキスパートガイド
  8. C言語における配列とポインタの関係を理解する
  9. C言語: アドレスとポインタを関数に渡す – 実践ガイド
  10. C言語 構造体とポインタ: 実践ガイド
  11. C++配列を徹底解説:宣言、初期化、ポインタ活用テクニック