読み込み中...

初心者から上級者まで理解深まる!C++で配列宣言の5つの実例付き解説

C++で配列を宣言する方法を学ぶイメージ C++
この記事は約21分で読めます。

【サイト内のコードはご自由に個人利用・商用利用いただけます】

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

本記事のサンプルコードを活用して機能追加、目的を達成できるように作ってありますので、是非ご活用ください。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を満たす現役のプログラマチームによって監修されています。

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

はじめに

C++は高性能かつ汎用性の高いプログラミング言語です。

この言語はシステムプログラミングからアプリケーション開発まで、幅広い分野で使用されています。

その特徴は、直接的なメモリ操作やポインタの使用が可能であり、高度な制御が行える点にあります。

また、オブジェクト指向プログラミングをサポートしており、複雑なソフトウェアの開発にも適しています。

C++の学習を始めるにあたって、基本的な構文の理解は必須です。

特に、配列の宣言と使用方法はC++プログラミングの基礎中の基礎と言えるでしょう。

配列は、同一の型の変数を連続したメモリ領域に格納するデータ構造で、多くのプログラミングタスクで頻繁に用いられます。

この記事では、C++における配列の宣言から始め、配列を効果的に使用する方法について詳しく解説します。

初心者から上級者まで、一層の理解を深めることができる内容となっています。

●C++とは

C++は、1980年代にBjarne Stroustrupによって開発されたプログラミング言語で、C言語の拡張版として設計されました。

C言語の効率的な記述能力と低レベル操作の能力を維持しつつ、クラスや継承、多態性などのオブジェクト指向の概念を取り入れています。

その結果、C++は高度なアプリケーション開発やシステムレベルのプログラミングに適した言語となりました。

C++の特徴の一つは、そのパフォーマンスの高さです。

コンパイル時に高度な最適化が行われるため、実行時の速度が速くなります。

また、直接メモリを操作できるため、システムプログラミングにも適しています。

一方で、オブジェクト指向機能を備えているため、大規模なソフトウェアの開発にも柔軟に対応できます。

さらに、C++は標準テンプレートライブラリ(STL)を含む豊富なライブラリを持っています。

これにより、データ構造やアルゴリズムなどを簡単に利用でき、開発の効率が大きく向上します。

○C++の基本

C++を学ぶ上で、まず理解すべきは基本的な構文とプログラミングの概念です。C++のコードは、関数と呼ばれる単位で構成されます。

最も基本的な関数はmain関数で、プログラムの実行開始点となります。

変数は、データを格納するための名前付きのメモリ領域です。C++では、変数を使用する前にその型を宣言する必要があります。

これには、整数型(int)、浮動小数点型(float, double)、文字型(char)などがあります。

C++では、制御構造としてif文やfor文、while文などがあります。

これらはプログラムの流れを制御するために使用され、条件分岐や繰り返し処理を実現します。

また、C++の大きな特徴として、クラスとオブジェクト指向プログラミングが挙げられます。

クラスはデータとそれを操作する関数(メソッド)を一つにまとめたもので、オブジェクト指向プログラミングでは、これらのクラスを使ってプログラムを構築します。

●配列の基本

配列はC++プログラミングにおいて基本的で重要な要素です。

同じ型の変数を一列に並べたデータ構造で、複数のデータを効率的に管理し操作することができます。

C++で配列を使うと、データの集合を扱う際に一つ一つ別々の変数としてではなく、一つの名前で管理し、繰り返し処理などを通じて効率的にアクセスできます。

○配列とは

配列は複数の要素が一定の順序で並んだ集まりで、これらの要素は通常、同じ型を持ちます。

配列内の各要素は、インデックス(または添字)と呼ばれる番号でアクセスされ、インデックスは0から始まります。

配列の使用は、関連するデータを単一の変数名で効率的に扱うために重要です。

例えば、100人の学生のテストスコアを記録する場合、100個の異なる変数を作成する代わりに、一つの配列を使用できます。

○配列の宣言方法

C++で配列を宣言するにはいくつかの方法があります。

一般的な方法は、配列の型(例:int, double)、配列の名前、および配列のサイズ(配列に格納できる要素の数)を指定するものです。

また、配列を宣言すると同時に初期化する方法もあります。

この場合、配列のサイズは初期化に使用される値の数に自動的に設定されます。

例えば、10個の整数を格納できる配列を宣言するには int scores[10]; と書き、4つの実数値を持つ配列を初期化するには double temperatures[] = {22.5, 25.0, 23.5, 21.0}; と書きます。

配列が宣言されると、その要素にアクセスし、値を読み書きすることができます。

●配列の初期化

配列を扱う上で重要な概念の一つが配列の初期化です。

初期化とは、配列に初めて値を割り当てる操作を指します。

C++では、配列を宣言する際に同時に初期化を行う方法と、宣言後に値を割り当てる方法の二つが存在します。

配列の初期化にはいくつかの方法があります。

例えば、宣言時にすべての要素に特定の値を割り当てることも、特定の要素だけに値を割り当てて残りをデフォルト値で初期化することもできます。

また、配列のサイズを省略して初期化子リストを使うことで、コンパイラにサイズを自動で判断させることも可能です。

ここでは、配列の静的初期化と動的初期化について説明し、それぞれの特徴と使い方について詳しく見ていきましょう。

○配列の静的初期化

配列の静的初期化とは、コンパイル時に配列のサイズと初期値が決定される方法です。

これは最も一般的な配列の初期化方法で、特に初心者にとって理解しやすい方法と言えます。

例えば、下記のコードは整数型の配列を宣言し、それぞれの要素を0から4までの値で初期化しています。

int numbers[5] = {0, 1, 2, 3, 4};

このコードでは、配列numbersが5つの整数を格納するように宣言されています。

初期化子リスト{0, 1, 2, 3, 4}を使用して、配列の各要素に値を割り当てています。

この方法では、配列のサイズが明示的に指定されており、初期化子リストの要素数と一致している必要があります。

また、次のように初期化子リストを省略することで、自動的に配列の要素をデフォルト値(この場合は0)で初期化することもできます。

int numbers[5] = {};

このコードでは、numbers配列の各要素が0で初期化されます。

この方法は、配列の要素を特定のデフォルト値で一括して初期化したい場合に便利です。

○配列の動的初期化

配列の動的初期化は、実行時に配列のサイズや値を決定する方法です。

この方法を使用すると、プログラムの実行中に配列のサイズや初期値を変更することが可能になります。

動的配列は、new演算子を使用してメモリを動的に割り当てることで実現されます。

例えば、下記のコードは実行時にユーザーから入力を受け取り、そのサイズの整数型配列を動的に作成します。

int size;
std::cin >> size;
int* numbers = new int[size];

このコードでは、まずsize変数を宣言し、ユーザーから配列のサイズを入力してもらいます。

次に、new演算子を使って入力されたサイズの整数型配列numbersを動的に生成します。

この方法では、配列のサイズが実行時に決定されるため、柔軟な配列操作が可能ですが、メモリ管理に注意が必要です。

●配列の操作

C++における配列の操作は、プログラミングの基本的なスキルであり、効率的なデータ管理に欠かせません。

配列を操作するには、まずその要素にアクセスし、必要に応じて値を更新することが必要です。

これにより、データの一括処理や、様々なアルゴリズムの実装が可能になります。

配列操作の基本には、要素へのアクセス、要素の更新、要素の検索、要素のソートなどが含まれます。

これらの操作を理解し、適切に使いこなすことで、C++プログラミングの幅が大きく広がります。

○配列要素のアクセス

C++での配列要素へのアクセスは、配列のインデックスを使って行います。

配列のインデックスは0から始まり、配列の長さ未満の整数である必要があります。

例えば、5つの要素を持つ配列int myArray[5]がある場合、最初の要素はmyArray[0]、最後の要素はmyArray[4]としてアクセスします。

インデックスを使ったアクセスは、配列の任意の位置にあるデータを読み書きする際に不可欠です。

このコードは、5つの要素を持つ整数の配列にアクセスし、各要素の値を出力するものです。

この例では、forループを使って配列の各要素に順番にアクセスし、その値を表示しています。

#include <iostream>
using namespace std;

int main() {
    int myArray[5] = {1, 2, 3, 4, 5};
    for(int i = 0; i < 5; i++) {
        cout << "要素[" << i << "]: " << myArray[i] << endl;
    }
    return 0;
}

このコードを実行すると、配列myArrayの各要素の値が出力されます。

出力結果は下記のようになります。

要素[0]: 1
要素[1]: 2
要素[2]: 3
要素[3]: 4
要素[4]: 5

○配列要素の更新

配列の要素を更新するには、特定のインデックスに新しい値を代入します。

例えば、配列の特定の要素を変更するには、その要素のインデックスを指定し、新しい値を代入するだけです。

配列要素の更新は、配列内のデータを動的に変更したい場合に特に重要です。

ここでは、先ほどの配列myArrayの第3要素(インデックス2)の値を10に更新するサンプルコードを紹介します。

#include <iostream>
using namespace std;

int main() {
    int myArray[5] = {1, 2, 3, 4, 5};
    myArray[2] = 10; // インデックス2の要素を10に更新

    for(int i = 0; i < 5; i++) {
        cout << "要素[" << i << "]: " << myArray[i] << endl;
    }
    return 0;
}

このコードを実行すると、myArray[2]の値が10に更新され、出力結果は下記のように変わります。

要素[0]: 1
要素[1]: 2
要素[2]: 10
要素[3]: 4
要素[4]: 5

●配列の応用

C++における配列の応用方法について説明します。

配列は単純なデータ構造から複雑なデータ処理まで、幅広い用途で活用されます。

ここでは、具体的な応用例を通じて、C++での配列の使い方を深く理解しましょう。

○サンプルコード1:配列を使ったデータ集計

配列を利用してデータを集計する方法を見てみましょう。

下記のサンプルコードでは、学生の点数を配列に格納し、その平均点を計算しています。

#include <iostream>
using namespace std;

int main() {
    int scores[] = {70, 85, 62, 90, 76};
    int sum = 0;
    int size = sizeof(scores) / sizeof(scores[0]);

    for (int i = 0; i < size; i++) {
        sum += scores[i];
    }

    double average = static_cast<double>(sum) / size;
    cout << "平均点は " << average << " 点です。" << endl;

    return 0;
}

このコードは、scores 配列に5人の学生の点数を格納し、for ループを使って合計点を計算しています。

その後、合計点を学生数で割って平均点を求めています。

この例では、配列の基本的な使い方とループ処理の組み合わせが表されています。

実行すると、このコードは学生の平均点を出力します。

○サンプルコード2:配列を使った簡単なソート

次に、配列を使ってデータをソートする基本的な方法を紹介します。

下記のコードは、選択ソートアルゴリズムを使用して配列内の数値を昇順に並び替える例です。

#include <iostream>
using namespace std;

void swap(int &a, int &b) {
    int temp = a;
    a = b;
    b = temp;
}

int main() {
    int numbers[] = {35, 10, 55, 20, 5};
    int size = sizeof(numbers) / sizeof(numbers[0]);

    for (int i = 0; i < size - 1; i++) {
        for (int j = i + 1; j < size; j++) {
            if (numbers[i] > numbers[j]) {
                swap(numbers[i], numbers[j]);
            }
        }
    }

    cout << "ソート後の配列: ";
    for (int i = 0; i < size; i++) {
        cout << numbers[i] << " ";
    }
    cout << endl;

    return 0;
}

このコードは、外側のループが配列の各要素を走査し、内側のループがその要素より後ろにある各要素と比較して、必要に応じて値を交換しています。

このプロセスを繰り返すことで、配列が昇順に並び替えられます。

実行すると、このコードはソートされた数値の配列を出力します。

○サンプルコード3:多次元配列の使用

最後に、多次元配列の使用例を見てみましょう。

下記のサンプルコードでは、2次元配列を使用して行と列の概念を表現し、簡単な行列のデータを操作しています。

#include <iostream>
using namespace std;

int main() {
    int matrix[2][3] = {{1, 2, 3}, {4, 5, 6}};
    int rows = 2;
    int cols = 3;

    cout << "元の行列:" << endl;
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            cout << matrix[i][j] << " ";
        }
        cout << endl;
    }

    // 行列の各要素に2を足す
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            matrix[i][j] += 2;
        }
    }

    cout << "更新後の行列:" << endl;
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            cout << matrix[i][j] << " ";
        }
        cout << endl;
    }

    return 0;
}

このコードでは、2行3列の行列が作成され、その後、行列の各要素に2が加えられています。

多次元配列を使用すると、表や行列など、より複雑なデータ構造を表現することが可能になります。

実行すると、このコードは元の行列と更新後の行列を出力します。

これにより、多次元配列を使ったデータの表現と操作の方法が示されています。

●配列の注意点と対処法

C++で配列を使用する際にはいくつかの注意点があります。

まず、配列は固定サイズを持つため、宣言時にそのサイズを定義する必要があります。

このサイズはプログラム実行中に変更することができません。

この制限は配列の使用において最も重要な点の一つです。

もし配列のサイズを超えてアクセスしようとすると、未定義の振る舞いが発生し、プログラムがクラッシュする可能性があります。

配列のサイズを超えるアクセスを防ぐためには、配列のサイズを常に把握し、範囲外アクセスが発生しないように注意深くプログラミングする必要があります。

例えば、forループを使用して配列を処理する場合、ループの条件を配列のサイズに合わせて正しく設定することが重要です。

また、配列を関数に渡す際には、サイズ情報も一緒に渡す必要があります。

C++では配列が関数に渡されると、その配列はポインタに変換されるため、元の配列のサイズ情報が失われます。

そのため、関数に配列を渡す際には、サイズ情報も一緒に渡すか、std::arrayやstd::vectorなどのコンテナを使用することが推奨されます。

○配列のサイズ管理

配列のサイズ管理にはいくつかの方法があります。

固定サイズの配列は、宣言時にサイズが決定されます。

例えば、int arr[10]; と宣言すれば、サイズが10の整数型配列が作成されます。

しかし、この方法では実行時にサイズを変更することができません。

実行時にサイズを変更可能な配列を作成するには、動的メモリ割り当てを使用します。

これは、new キーワードを使用して実行時にメモリを割り当て、サイズを指定することで行います。

例えば、int* arr = new int[10]; とすることで、サイズ10の整数型配列が動的に割り当てられます。

動的配列は使用後に delete[] を使ってメモリを解放する必要があります。

動的配列の使用例としては、下記のコードがあります。

#include <iostream>

int main() {
    int size;
    std::cout << "配列のサイズを入力してください: ";
    std::cin >> size;

    int* arr = new int[size];

    for (int i = 0; i < size; i++) {
        arr[i] = i * i;
    }

    for (int i = 0; i < size; i++) {
        std::cout << "arr[" << i << "] = " << arr[i] << std::endl;
    }

    delete[] arr;

    return 0;
}

このコードは、ユーザーから配列のサイズを入力してもらい、そのサイズの整数型配列を動的に作成します。

その後、各要素にそのインデックスの二乗を格納し、内容を表示します。

プログラムの最後で delete[] を使用して配列のメモリを解放しています。

このコードを実行すると、下記のような出力が得られます。

配列のサイズを入力してください: 5
arr[0] = 0
arr[1] = 1
arr[2] = 4
arr[3] = 9
arr[4] = 16

○配列のメモリ管理

配列のメモリ管理は非常に重要です。

特に動的配列を使用する場合には、使用後のメモリリークを防ぐために、必ず delete[] を使用してメモリを解放する必要があります。

メモリリークはプログラムのパフォーマンスに影響を与える可能性があるため、配列のライフサイクルを適切に管理することが重要です。

また、C++11以降ではスマートポインタを使用することで、自動的にメモリ管理を行うことができます。

例えば、std::unique_ptr<int[]>std::shared_ptr<int[]> を使用すると、スコープを抜ける際に自動的にメモリが解放されます。

これにより、メモリリークを防ぎつつ、コードの安全性と可読性を向上させることができます。

●配列のカスタマイズ方法

C++における配列のカスタマイズ方法は多岐にわたり、プログラムのニーズに応じて様々な形で配列を使用することができます。

ここでは、特に配列の動的サイズ変更とカスタムデータ型の使用に焦点を当てて、これらの応用例を紹介します。

○サンプルコード4:配列の動的サイズ変更

C++において、配列のサイズは通常、コンパイル時に固定されますが、動的メモリ割り当てを利用することで、実行時に配列のサイズを変更することが可能です。

下記のサンプルコードは、ユーザーから入力されたサイズに基づいて整数の配列を動的に生成し、その後サイズを変更する方法を表しています。

#include <iostream>
using namespace std;

int main() {
    int initialSize;
    cout << "初期サイズを入力してください: ";
    cin >> initialSize;

    int* arr = new int[initialSize];  // 初期サイズで配列を動的に確保

    // 配列を新しいサイズに再確保
    int newSize;
    cout << "新しいサイズを入力してください: ";
    cin >> newSize;
    int* newArr = new int[newSize];

    // 既存のデータを新しい配列にコピー
    for (int i = 0; i < initialSize && i < newSize; i++) {
        newArr[i] = arr[i];
    }

    delete[] arr;  // 古い配列のメモリを解放
    arr = newArr;  // 新しい配列を指すように更新

    // 新しい配列に追加データを入力
    for (int i = initialSize; i < newSize; i++) {
        cout << "新しい要素" << i << "の値を入力: ";
        cin >> arr[i];
    }

    // 新しい配列の内容を表示
    for (int i = 0; i < newSize; i++) {
        cout << "arr[" << i << "] = " << arr[i] << endl;
    }

    delete[] arr;  // 最終的な配列のメモリを解放
    return 0;
}

このコードは、ユーザーからの入力に基づいて配列のサイズを変更し、新しいデータを追加しています。

動的配列は使用後に必ずメモリを解放する必要があるため、delete[]を使用しています。

○サンプルコード5:配列のカスタムデータ型

C++では、カスタムデータ型(クラスや構造体)を配列の要素として使用することができます。

これにより、複雑なデータ構造を配列内で管理することが可能になります。

下記のサンプルコードは、カスタムデータ型を使用した配列の例を表しています。

#include <iostream>
#include <string>
using namespace std;

class Student {
public:
    string name;
    int score;

    Student(string n, int s) : name(n), score(s) {}
};

int main() {
    Student students[] = {
        Student("Alice", 90),
        Student("Bob", 85),
        Student("Charlie", 95)
    };

    for (int i = 0; i < 3; i++) {
        cout << students[i].name << "のスコア: " << students[i].score << endl;
    }

    return 0;
}

このコードでは、Studentクラスを定義し、名前とスコアを属性として持たせています。

その後、Studentオブジェクトの配列を作成し、各学生のデータを初期化しています。

このようにして、配列を使って複数のカスタムデータ型のインスタンスを効率的に管理することができます。

実行すると、このコードは各学生の名前とスコアを出力します。

この例では、オブジェクト指向プログラミングの原則を活用して、データをより構造化し管理する方法を表しています。

まとめ

この記事では、C++における配列の宣言、初期化、操作、応用例、注意点と対処法、さらにカスタマイズ方法について詳細に解説しました。

初心者から上級者までが理解できるように、基本的な配列の使用から複雑な動的配列やカスタムデータ型を使った応用例までを幅広くカバーしました。

これらの知識を活用することで、C++プログラミングのスキルをさらに深めることができるでしょう。