配列

複数のデータをまとめて管理する方法

概要

これまで学んだ変数は1つの値を保存するものでした。 しかし、10個の成績、100個のセンサー値など、 複数のデータを管理する必要がしばしばあります。

配列は、 同じ型の複数のデータを、 メモリ上に連続して保存し、 効率よく管理する仕組みです。

配列の基本

宣言と初期化

// 宣言(10個の整数を保存できる配列)
int scores[10];

// 宣言と初期化
int numbers[5] = {10, 20, 30, 40, 50};

// サイズを省略(初期化子から自動判定)
int data[] = {1, 2, 3, 4, 5};  // サイズは5

インデックスでアクセス

int arr[3] = {10, 20, 30};

std::cout << arr[0] << std::endl;  // 10(最初の要素)
std::cout << arr[1] << std::endl;  // 20
std::cout << arr[2] << std::endl;  // 30

// 値の変更
arr[1] = 25;
std::cout << arr[1] << std::endl;  // 25

重要:インデックスは0から開始です。

配列の実例

例1: 7日間の気温を保存

#include <iostream>

int main() {
    int temps[7] = {20, 22, 19, 23, 25, 24, 21};  // 1週間の気温
    
    // 平均気温を計算
    int sum = 0;
    for (int i = 0; i < 7; i++) {
        sum += temps[i];
    }
    
    double average = sum / 7.0;
    std::cout << "平均気温: " << average << "度" << std::endl;
    
    return 0;
}

平均気温: 22.2857度

例2: 学生の成績検索

#include <iostream>

int main() {
    int scores[5] = {85, 92, 78, 88, 95};
    
    int maxScore = scores[0];
    int maxIndex = 0;
    
    for (int i = 1; i < 5; i++) {
        if (scores[i] > maxScore) {
            maxScore = scores[i];
            maxIndex = i;
        }
    }
    
    std::cout << "最高点: " << maxScore << std::endl;
    std::cout << "順位: " << (maxIndex + 1) << "番目" << std::endl;
    
    return 0;
}

最高点: 95
順位: 5番目

2次元配列

2次元配列は、 行と列で表現できるテーブル形式のデータに使います。

// 3行4列の2次元配列
int matrix[3][4] = {
    {1, 2, 3, 4},
    {5, 6, 7, 8},
    {9, 10, 11, 12}
};

// アクセス
std::cout << matrix[0][0] << std::endl;  // 1
std::cout << matrix[1][2] << std::endl;  // 7
std::cout << matrix[2][3] << std::endl;  // 12

例:成績表

#include <iostream>

int main() {
    // 学生4名、3科目の成績
    int grades[4][3] = {
        {80, 90, 85},  // 学生1
        {75, 88, 92},  // 学生2
        {95, 87, 89},  // 学生3
        {70, 75, 80}   // 学生4
    };
    
    // 科目別の平均点を計算
    for (int subject = 0; subject < 3; subject++) {
        int sum = 0;
        for (int student = 0; student < 4; student++) {
            sum += grades[student][subject];
        }
        std::cout << "科目" << (subject + 1) << "の平均: " << (sum / 4.0) << std::endl;
    }
    
    return 0;
}

科目1の平均: 80
科目2の平均: 85
科目3の平均: 86.5

配列と関数

関数に配列を渡す場合、 配列の名前を渡すと、 自動的に配列のアドレス(参照)が渡されるため、 関数内で配列を変更できます。

#include <iostream>

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

int main() {
    int numbers[5] = {1, 2, 3, 4, 5};
    
    std::cout << "変更前: ";
    for (int x : numbers) std::cout << x << " ";
    std::cout << std::endl;
    
    addOne(numbers, 5);
    
    std::cout << "変更後: ";
    for (int x : numbers) std::cout << x << " ";
    std::cout << std::endl;
    
    return 0;
}

変更前: 1 2 3 4 5
変更後: 2 3 4 5 6

範囲ベースの for ループ

C++11以降、範囲ベースの for ループを使って、 配列の各要素に簡単にアクセスできます。

#include <iostream>

int main() {
    int nums[] = {10, 20, 30, 40, 50};
    
    // 通常の for ループ
    std::cout << "通常: ";
    for (int i = 0; i < 5; i++) {
        std::cout << nums[i] << " ";
    }
    std::cout << std::endl;
    
    // 範囲ベースの for ループ
    std::cout << "範囲ベース: ";
    for (int num : nums) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
    
    return 0;
}

通常: 10 20 30 40 50
範囲ベース: 10 20 30 40 50

ポイント

  • 配列は複数の同じ型のデータをまとめて管理
  • インデックスは0から開始
  • 2次元配列でテーブル形式のデータを表現
  • 関数への配列渡しは自動的に参照(アドレス)
  • 範囲ベースthe for ループで簡潔に反復化

よくある誤り

誤り1: 配列のサイズを超えてアクセス

int arr[3] = {1, 2, 3};
std::cout << arr[3] << std::endl;  // 危険!: 存在しない領域にアクセス
std::cout << arr[10] << std::endl; // クラッシュ

誤り2: 配列のサイズを動的に変える

int arr[10];
arr[15] = 100;  // エラー!: 配列のサイズは変えられない

誤り3: 初期化子以外でのサイズ省略

int arr[];  // エラー!: 初期化子がないとサイズ不明

やってみよう

練習1: 10個の整数を入力させ、合計と平均を計算。

練習2: 配列の最大値と最小値を見つける関数。

練習3: 2つの配列を逆順でマージする関数。

チャレンジ: ソートアルゴリズム(バブルソート)の実装。

まとめ

  • 配列は複数データの効率的な管理
  • 配列と for ループでデータ処理が飛躍的に効率化
  • 2次元配列で複雑なデータ構造に対応
  • インデックス範囲に注意