[C++] foreachを使った配列の反復処理方法

C++では、範囲ベースのforループを使用して配列やコンテナの要素を簡単に反復処理できます。このループは、C++11で導入され、従来のforループよりも簡潔で読みやすいコードを提供します。

範囲ベースのforループは、配列やSTLコンテナの各要素に対して自動的に反復処理を行います。構文はfor (auto &element : container)のように記述し、elementには各要素が順に代入されます。

この方法は、特に要素の数が不明な場合や、コンテナの全要素に対して同じ操作を行いたい場合に便利です。

この記事でわかること
  • 配列をforeachループで反復処理する基本的な方法
  • 多次元配列やポインタを使った反復処理の応用例
  • コンテナクラスとforeachループの組み合わせによる利点
  • ラムダ式を活用したforeachループの柔軟な使い方
  • 範囲ベースforループと従来のforループの違いと利点

目次から探す

配列をforeachで反復処理する方法

配列を簡単に反復処理するためにforeachループ(範囲ベースforループ)が利用できます。

配列の初期化とforeachループの設定

まず、配列を初期化し、foreachループを設定する方法を見ていきましょう。

以下のサンプルコードでは、整数型の配列を初期化し、foreachループを使ってその要素を反復処理します。

#include <iostream>
#include <array>
int main() {
    // 配列の初期化
    std::array<int, 5> numbers = {1, 2, 3, 4, 5};
    // foreachループの設定
    for (int number : numbers) {
        std::cout << number << " ";
    }
    return 0;
}
1 2 3 4 5

このコードでは、std::arrayを使って配列を初期化し、foreachループで各要素を出力しています。

foreachループは、配列の要素を順番に処理するのに便利です。

配列の要素を出力する

配列の要素を出力するには、foreachループを使って各要素をstd::coutで表示します。

以下の例では、文字列型の配列を使って要素を出力しています。

#include <iostream>
#include <array>
int main() {
    // 文字列型の配列を初期化
    std::array<std::string, 3> fruits = {"Apple", "Banana", "Cherry"};
    // foreachループで要素を出力
    for (const std::string& fruit : fruits) {
        std::cout << fruit << std::endl;
    }
    return 0;
}
Apple
Banana
Cherry

このコードでは、const std::string&を使って要素を参照し、出力しています。

constを使うことで、要素が変更されないことを保証します。

配列の要素を変更する

配列の要素を変更する場合、foreachループで要素を参照する際に参照型を使います。

以下の例では、整数型の配列の要素を2倍にしています。

#include <iostream>
#include <array>
int main() {
    // 配列の初期化
    std::array<int, 5> numbers = {1, 2, 3, 4, 5};
    // foreachループで要素を変更
    for (int& number : numbers) {
        number *= 2; // 要素を2倍にする
    }
    // 変更後の要素を出力
    for (int number : numbers) {
        std::cout << number << " ";
    }
    return 0;
}
2 4 6 8 10

このコードでは、int&を使って要素を参照し、直接変更しています。

参照型を使うことで、配列の要素を効率的に変更できます。

配列の要素を条件付きで処理する

配列の要素を条件付きで処理する場合、foreachループ内で条件分岐を行います。

以下の例では、偶数の要素のみを出力しています。

#include <iostream>
#include <array>
int main() {
    // 配列の初期化
    std::array<int, 5> numbers = {1, 2, 3, 4, 5};
    // foreachループで条件付き処理
    for (int number : numbers) {
        if (number % 2 == 0) { // 偶数かどうかをチェック
            std::cout << number << " ";
        }
    }
    return 0;
}
2 4

このコードでは、if文を使って偶数の要素のみを出力しています。

条件付きで処理を行うことで、特定の要素に対してのみ操作を行うことができます。

foreachループの応用例

foreachループは、単純な配列の反復処理だけでなく、さまざまな応用が可能です。

このセクションでは、foreachループの応用例をいくつか紹介します。

多次元配列の反復処理

多次元配列をforeachループで反復処理するには、ネストされたループを使用します。

以下の例では、2次元配列の要素を出力しています。

#include <iostream>
#include <array>
int main() {
    // 2次元配列の初期化
    std::array<std::array<int, 3>, 2> matrix = {{{1, 2, 3}, {4, 5, 6}}};
    // foreachループで多次元配列を反復処理
    for (const auto& row : matrix) {
        for (int element : row) {
            std::cout << element << " ";
        }
        std::cout << std::endl;
    }
    return 0;
}
1 2 3
4 5 6

このコードでは、autoを使って行を参照し、各行の要素を出力しています。

多次元配列を処理する際には、ネストされたforeachループが便利です。

ポインタを使った配列の反復処理

ポインタを使って配列を反復処理することも可能です。

以下の例では、ポインタを使って配列の要素を出力しています。

#include <iostream>
int main() {
    // 配列の初期化
    int numbers[] = {1, 2, 3, 4, 5};
    int* ptr = numbers; // 配列の先頭を指すポインタ
    // ポインタを使った反復処理
    for (int i = 0; i < 5; ++i) {
        std::cout << *(ptr + i) << " ";
    }
    return 0;
}
1 2 3 4 5

このコードでは、ポインタを使って配列の各要素にアクセスし、出力しています。

ポインタを使うことで、配列のメモリ操作を直接行うことができます。

コンテナクラスとforeachループの組み合わせ

C++の標準ライブラリには、std::vectorstd::listなどのコンテナクラスがあります。

これらのコンテナクラスもforeachループで反復処理できます。

#include <iostream>
#include <vector>
int main() {
    // ベクターの初期化
    std::vector<int> numbers = {10, 20, 30, 40, 50};
    // foreachループでベクターを反復処理
    for (int number : numbers) {
        std::cout << number << " ";
    }
    return 0;
}
10 20 30 40 50

このコードでは、std::vectorをforeachループで反復処理しています。

コンテナクラスを使うことで、動的な配列操作が可能になります。

ラムダ式とforeachループの活用

ラムダ式を使うことで、foreachループ内でより柔軟な処理を行うことができます。

以下の例では、ラムダ式を使って配列の要素を出力しています。

#include <iostream>
#include <vector>
#include <algorithm>
int main() {
    // ベクターの初期化
    std::vector<int> numbers = {1, 2, 3, 4, 5};
    // ラムダ式を使ったforeachループ
    std::for_each(numbers.begin(), numbers.end(), [](int number) {
        std::cout << number << " ";
    });
    return 0;
}
1 2 3 4 5

このコードでは、std::for_eachとラムダ式を組み合わせて、ベクターの要素を出力しています。

ラムダ式を使うことで、簡潔に処理を記述できます。

範囲ベースforループとの比較

範囲ベースforループ(foreachループ)は、従来のforループと比較して、コードが簡潔で読みやすくなります。

以下の表で、範囲ベースforループと従来のforループの違いを比較します。

スクロールできます
特徴範囲ベースforループ従来のforループ
コードの簡潔さ高い低い
可読性高い低い
配列のサイズ指定不要必要
イテレータの使用自動手動

範囲ベースforループは、配列やコンテナの要素を簡単に反復処理できるため、特に要素数が不明な場合や可読性を重視する場合に有効です。

よくある質問

foreachループはどのような場合に使うべきですか?

foreachループは、配列やコンテナの全要素を順番に処理したい場合に使うべきです。

特に、要素数が不明な場合や、要素のインデックスを意識せずに処理を行いたい場合に便利です。

コードが簡潔になり、可読性が向上するため、要素の順次処理が目的であればforeachループを選択するのが良いでしょう。

foreachループとforループの違いは何ですか?

foreachループ(範囲ベースforループ)と従来のforループの主な違いは以下の通りです:

  • 構文の簡潔さ: foreachループは、要素の反復処理を簡潔に記述できます。

例:for (int number : numbers) {}

  • 可読性: foreachループは、インデックスを使わないため、コードが読みやすくなります。
  • 配列のサイズ指定: foreachループでは、配列やコンテナのサイズを明示的に指定する必要がありません。
  • イテレータの使用: foreachループは、内部でイテレータを自動的に使用するため、手動でイテレータを扱う必要がありません。

foreachループはすべてのコンテナで使えますか?

foreachループは、C++の標準ライブラリで提供されているほとんどのコンテナで使用できます。

具体的には、std::vectorstd::arraystd::liststd::setstd::mapなどのコンテナで利用可能です。

ただし、foreachループを使用するためには、コンテナがイテレータをサポートしている必要があります。

イテレータをサポートしていない独自のデータ構造では、foreachループを直接使用することはできません。

まとめ

この記事では、C++23におけるforeachループを使った配列の反復処理方法について詳しく解説しました。

foreachループの基本的な使い方から、多次元配列やポインタ、コンテナクラスとの組み合わせ、さらにはラムダ式を用いた応用例まで幅広く取り上げました。

これを機に、foreachループを活用して、より効率的で読みやすいコードを書くことに挑戦してみてはいかがでしょうか。

当サイトはリンクフリーです。出典元を明記していただければ、ご自由に引用していただいて構いません。

関連カテゴリーから探す

  • 条件分岐 (11)
  • 繰り返し処理 (11)
  • URLをコピーしました!
目次から探す