6日でできる 新C言語入門|配列の基本と応用を演習で学ぶ

以下に、記事としてそのまま使いやすい形で作成しました。

配列は、たくさんのデータをまとめて扱うための大切な道具。
表示、抽出、集計、2次元配列の演習を通して、C言語の配列処理を実践的に身につけよう。

C言語で複数のデータを扱うとき、配列はとても重要な役割を持ちます。たとえば、複数人の点数、気温の一覧、売上データ、計算結果の表など、同じ種類の値をまとめて管理したい場面で配列が活躍します。

配列を使わずに、score1、score2、score3のように変数を1つずつ用意することもできます。しかし、データの数が増えるほど、変数名が多くなり、処理も書きにくくなります。配列を使えば、同じ型のデータを1つの名前でまとめて扱えるため、for文やwhile文と組み合わせて効率よく処理できます。

配列の基本では、まず要素を順番に表示することから始めます。そこから、条件に合う値だけを取り出す処理、合計や平均、最大値や最小値を求める処理へ進むと、配列の便利さがよく分かります。

さらに、2次元配列を使うと、表のような行と列を持つデータも扱えるようになります。九九表や成績表のように、縦横の形でデータを管理したいときに役立ちます。

この記事では、1次元配列の基本操作から、条件による要素の抽出、2次元配列を使った表の作成、配列要素の集計、ループを使った演習まで、サンプルプログラムを通して順番に学んでいきます。

配列は複数の値をひとまとまりで扱える

配列は、同じ型の値を複数まとめて管理する仕組みです。たとえば、int型の値を7個まとめて扱いたい場合は、次のように書けます。

int data[7];

この宣言では、dataという名前の配列に、int型の値を7個格納できます。配列の各要素には、添え字を使ってアクセスします。

data[0]
data[1]
data[2]

C言語の配列では、添え字は0から始まります。要素数が7の場合、有効な添え字は0から6までです。

要素数有効な添え字
30, 1, 2
50, 1, 2, 3, 4
70, 1, 2, 3, 4, 5, 6

配列を学ぶときは、要素数と添え字の関係をしっかり押さえることが大切です。要素数が7だからといって、data[7]を使えるわけではありません。data[7]は8番目の要素を意味するため、範囲外アクセスになります。

配列の全要素を表示する

まずは、1次元配列のすべての要素をfor文で表示する基本的な演習です。

配列は、添え字を0から順番に増やしていけば、すべての要素にアクセスできます。そのため、for文との相性がとてもよいです。

プロジェクト/ファイル名: Lesson36_1/main.c

#include <stdio.h>

int main(void) {
    int data[] = { 12, -5, 8, 0, 15, -2, 6 };
    int i;

    // 配列の要素を先頭から順番に表示する
    for (i = 0; i < 7; i++) {
        printf("%d ", data[i]);
    }

    printf("\n");

    return 0;
}

実行結果

12 -5 8 0 15 -2 6

このプログラムでは、data配列に7個の整数を入れています。

int data[] = { 12, -5, 8, 0, 15, -2, 6 };

要素数を省略して初期化しているため、初期化に使った値の個数から、配列の要素数が決まります。この場合、値は7個あるので、dataは7個の要素を持つ配列になります。

for文では、iを0から6まで変化させています。

for (i = 0; i < 7; i++)

iが0のときはdata[0]、iが1のときはdata[1]というように、配列の要素を順番に表示しています。

図:1次元配列をfor文で順番に処理する

この図から分かること

この図から分かるのは、配列の要素は添え字を使って順番に取り出せるということです。

for文のカウンタiを0から順番に増やすことで、data[0]、data[1]、data[2]というように、配列の全要素へアクセスできます。配列とfor文を組み合わせると、複数のデータをまとめて処理しやすくなります。

配列とfor文の組み合わせが便利な理由

配列の要素を1つずつ表示するだけなら、printfを何回も書くこともできます。

printf("%d ", data[0]);
printf("%d ", data[1]);
printf("%d ", data[2]);

しかし、要素数が増えると、この書き方は大変です。配列の要素数が10個、100個と増えた場合、printfを何度も書くのは効率がよくありません。

for文を使えば、添え字を順番に変化させながら、同じ処理を繰り返せます。

処理方法特徴
要素を1つずつ書く要素数が少ない場合は分かりやすいが、数が増えると大変
for文で処理する要素数が多くても同じ形で処理できる
配列とfor文を組み合わせる表示、検索、集計などに応用しやすい

配列を使いこなすには、for文で添え字を動かす感覚に慣れることが大切です。

条件に合う要素だけを取り出す

配列では、すべての要素を表示するだけでなく、条件に合う要素だけを取り出すこともできます。

たとえば、次のような条件で要素を選べます。

取り出したい要素条件式の例
偶数data[i] % 2 == 0
正の数data[i] > 0
負の数data[i] < 0
10以上の数data[i] >= 10
0ではない数data[i] != 0

このように、for文で配列を順番に見ながら、if文で条件を判定すると、必要な要素だけを処理できます。

偶数だけを表示する

次のプログラムでは、配列の中から偶数だけを表示します。

プロジェクト/ファイル名: Lesson36_2/main.c

#include <stdio.h>

int main(void) {
    int data[] = { 12, -5, 8, 0, 15, -2, 6 };
    int i;

    // 配列の中から偶数だけを表示する
    for (i = 0; i < 7; i++) {
        if (data[i] % 2 == 0) {
            printf("%d ", data[i]);
        }
    }

    printf("\n");

    return 0;
}

実行結果

12 8 0 -2 6

このプログラムでは、data[i] % 2 == 0という条件で偶数かどうかを判定しています。

%は余りを求める演算子です。2で割った余りが0なら、その数は偶数です。

if (data[i] % 2 == 0)

この条件が成り立つときだけprintfが実行されます。そのため、配列の中から偶数だけが表示されます。

0も2で割った余りが0なので、偶数として表示されます。

正の数だけを表示する

次のプログラムでは、配列の中から正の数だけを表示します。

プロジェクト/ファイル名: Lesson36_3/main.c

#include <stdio.h>

int main(void) {
    int data[] = { 12, -5, 8, 0, 15, -2, 6 };
    int i;

    // 0より大きい値だけを表示する
    for (i = 0; i < 7; i++) {
        if (data[i] > 0) {
            printf("%d ", data[i]);
        }
    }

    printf("\n");

    return 0;
}

実行結果

12 8 15 6

このプログラムでは、data[i] > 0という条件で正の数かどうかを判定しています。

0は正の数ではないため、表示されません。負の数である-5や-2も表示されません。

配列の全要素を順番に調べながら、条件に合ったものだけを表示する流れは、実用的なプログラムでもよく使います。たとえば、合格点以上の点数だけを表示する、在庫がある商品だけを表示する、異常値だけを抽出する、といった処理に応用できます。

図:for文とif文で条件に合う要素だけを取り出す

この図から分かること

この図から分かるのは、配列の要素をfor文で順番に確認し、if文で条件に合うかどうかを判定できるということです。

偶数だけ、正の数だけ、負の数だけ、10以上だけのように、条件を変えることで取り出す要素を自由に変えられます。配列とif文を組み合わせると、必要なデータだけを選んで処理できるようになります。

条件抽出は配列処理の基本になる

配列の中から条件に合う要素だけを取り出す処理は、配列処理の基本です。

たとえば、点数データを扱う場合は、次のような処理が考えられます。

処理したい内容条件式の例
合格点以上を表示score[i] >= 60
100点だけを表示score[i] == 100
欠席扱いの値を除外score[i] >= 0
平均以上の値を表示score[i] >= avg

このように、配列とif文を組み合わせると、データの分類や抽出ができるようになります。

学習段階では、まず偶数、正の数、負の数のような分かりやすい条件から練習すると、配列処理の流れをつかみやすくなります。

2次元配列で表形式のデータを扱う

1次元配列は、データを横一列に並べるようなイメージです。一方、2次元配列を使うと、行と列を持つ表のようなデータを扱えます。

2次元配列の基本は次の形です。

型 配列名[行数][列数];

たとえば、9行9列の整数配列は次のように宣言できます。

int table[9][9];

2次元配列では、table[行][列]の形で要素にアクセスします。行と列の添え字はどちらも0から始まります。

宣言意味
int table[3][4];3行4列のint型配列
int score[5][2];5行2列のint型配列
int mult[9][9];9行9列のint型配列

2次元配列は、for文の2重ループと組み合わせることで、すべての要素に順番にアクセスできます。外側のfor文で行を進め、内側のfor文で列を進めるイメージです。

2次元配列で九九表を作る

次のプログラムでは、2次元配列を使って九九表を作成し、表形式で表示します。

プロジェクト/ファイル名: Lesson36_4/main.c

#include <stdio.h>

int main(void) {
    int mult[9][9];
    int row, col;

    // 九九の計算結果を2次元配列に保存する
    for (row = 0; row < 9; row++) {
        for (col = 0; col < 9; col++) {
            mult[row][col] = (row + 1) * (col + 1);
        }
    }

    // 2次元配列の内容を九九表として表示する
    for (row = 0; row < 9; row++) {
        for (col = 0; col < 9; col++) {
            printf("%2d ", mult[row][col]);
        }

        // 1行分を表示したら改行する
        printf("\n");
    }

    return 0;
}

実行結果

 1  2  3  4  5  6  7  8  9
 2  4  6  8 10 12 14 16 18
 3  6  9 12 15 18 21 24 27
 4  8 12 16 20 24 28 32 36
 5 10 15 20 25 30 35 40 45
 6 12 18 24 30 36 42 48 54
 7 14 21 28 35 42 49 56 63
 8 16 24 32 40 48 56 64 72
 9 18 27 36 45 54 63 72 81

このプログラムでは、mult[9][9]という2次元配列を使っています。九九表は9行9列なので、2次元配列で表すと自然です。

rowとcolは0から始まります。しかし、九九の計算では1から9までを使いたいので、row + 1とcol + 1を使っています。

mult[row][col] = (row + 1) * (col + 1);

rowが0、colが0のときは、1 × 1の結果が入ります。rowが8、colが8のときは、9 × 9の結果が入ります。

表示では、%2dを使って数値の幅をそろえています。これにより、1桁と2桁の数が混ざっても表が見やすくなります。

2次元配列と2重ループの関係

2次元配列を処理するときは、for文の2重ループがよく使われます。

for (row = 0; row < 9; row++) {
    for (col = 0; col < 9; col++) {
        printf("%2d ", mult[row][col]);
    }
    printf("\n");
}

外側のfor文は行を担当します。内側のfor文は列を担当します。

ループ役割
外側のfor文行を進める
内側のfor文列を進める
printf現在の要素を表示する
改行1行分の表示が終わったあとに行う

2次元配列を表として表示したい場合は、内側のfor文で1行分を表示し、そのあとで改行します。改行の位置を間違えると、表の形が崩れてしまうため注意しましょう。

図:2次元配列で九九表を作る流れ

この図から分かること

この図から分かるのは、2次元配列では行と列の組み合わせによって各要素を管理できるということです。

九九表では、rowとcolの値を使って、どの段とどの掛ける数なのかを表せます。for文の2重ループを使うと、表のすべてのマスを順番に計算し、2次元配列へ保存できます。

配列要素の合計・平均・最大値・最小値を求める

配列は、データを保存するだけでなく、集計処理にもよく使います。

たとえば、複数の点数や測定値が配列に入っている場合、合計、平均、最大値、最小値を求めることができます。

求める値考え方
合計すべての要素を足す
平均合計を要素数で割る
最大値一番大きい値を探す
最小値一番小さい値を探す

これらの処理では、配列の要素をfor文で順番に見ながら、必要な変数を更新していきます。

配列の統計処理を行う

次のプログラムでは、配列に入っている点数について、合計、平均、最大値、最小値を求めます。

プロジェクト/ファイル名: Lesson36_5/main.c

#include <stdio.h>

int main(void) {
    int score[] = { 72, 85, 91, 64, 78, 88, 53, 96 };
    int i;
    int sum = 0;
    int max;
    int min;
    int len;
    double avg;

    // 配列の要素数を計算する
    len = sizeof(score) / sizeof(score[0]);

    // 最大値と最小値の初期値として先頭要素を使う
    max = score[0];
    min = score[0];

    // 配列の要素を順番に処理する
    for (i = 0; i < len; i++) {
        printf("%d ", score[i]);

        // 合計を更新する
        sum += score[i];

        // 最大値を更新する
        if (score[i] > max) {
            max = score[i];
        }

        // 最小値を更新する
        if (score[i] < min) {
            min = score[i];
        }
    }

    // 平均を計算する
    avg = sum / (double)len;

    printf("\n");
    printf("合計: %d\n", sum);
    printf("平均: %.2f\n", avg);
    printf("最大値: %d\n", max);
    printf("最小値: %d\n", min);

    return 0;
}

実行結果

72 85 91 64 78 88 53 96
合計: 627
平均: 78.38
最大値: 96
最小値: 53

このプログラムでは、score配列に8個の点数を入れています。

要素数は、sizeofを使って計算しています。

len = sizeof(score) / sizeof(score[0]);

sizeof(score)は配列全体のサイズ、sizeof(score[0])は1要素分のサイズです。配列全体のサイズを1要素分のサイズで割ることで、要素数を求められます。

合計はsumに加算していきます。

sum += score[i];

最大値と最小値は、現在の値と比較して更新します。

if (score[i] > max) {
    max = score[i];
}

if (score[i] < min) {
    min = score[i];
}

最大値と最小値を求めるときは、最初にmaxとminへscore[0]を入れておくと、配列の中の値を基準に比較できるため自然です。

平均を求めるときは小数に注意する

平均を求めるときは、整数同士の割り算に注意が必要です。

avg = sum / (double)len;

このように、lenをdouble型に変換してから割り算することで、小数を含む平均を求められます。

もしsum / lenのように整数同士で割り算すると、小数部分が切り捨てられてしまいます。平均値のように小数を扱いたい場合は、double型を使うことを意識しましょう。

while文で決まった回数だけ表示する

配列の演習では、for文だけでなくwhile文も確認しておくと、ループ処理全体の理解が深まります。

次のプログラムでは、while文を使ってメッセージを5回表示します。

プロジェクト/ファイル名: Lesson36_6/main.c

#include <stdio.h>

int main(void) {
    int count = 0;

    // countが5未満の間、メッセージを表示する
    while (count < 5) {
        printf("配列の演習を進めよう\n");
        count++;
    }

    return 0;
}

実行結果

配列の演習を進めよう
配列の演習を進めよう
配列の演習を進めよう
配列の演習を進めよう
配列の演習を進めよう

このプログラムでは、countを0から始めています。while文では、count < 5が成り立つ間だけ処理を繰り返します。

ループの中でcount++を実行しているため、countは1ずつ増えていきます。countが5になると条件が偽になり、while文を終了します。

while文では、条件に使っている変数をループ内で更新することが重要です。更新処理を忘れると、条件が変わらず無限ループになる可能性があります。

入力された2つの整数の範囲を表示する

最後に、for文の応用として、入力された2つの整数の間にある値を表示するプログラムを見てみましょう。

プロジェクト/ファイル名: Lesson36_7/main.c

#include <stdio.h>

int main(void) {
    int x, y;
    int start, end;
    int i;

    printf("1つ目の整数を入力してください: ");
    scanf("%d", &x);

    printf("2つ目の整数を入力してください: ");
    scanf("%d", &y);

    // 小さい方を開始値、大きい方を終了値にする
    if (x < y) {
        start = x;
        end = y;
    } else {
        start = y;
        end = x;
    }

    // startからendまで順番に表示する
    for (i = start; i <= end; i++) {
        printf("%d ", i);
    }

    printf("\n");

    return 0;
}

実行結果

1つ目の整数を入力してください: 7
2つ目の整数を入力してください: 3
3 4 5 6 7

このプログラムでは、2つの整数を入力し、小さい方から大きい方までの整数を表示しています。

xとyのどちらが小さいか分からないため、if文で比較してstartとendを決めています。

if (x < y) {
    start = x;
    end = y;
} else {
    start = y;
    end = x;
}

その後、for文でstartからendまで順番に表示します。

for (i = start; i <= end; i++)

このように、入力値に応じてループの開始値と終了値を変えると、柔軟な繰り返し処理を書けます。

Visual Studioでscanfを使う場合、環境設定によって警告が表示されることがあります。学習用として動作確認する場合は、必要に応じてSDLチェックの設定も確認しておきましょう。

配列演習で身につけたい考え方

配列の演習では、単にプログラムを写して実行するだけでなく、次のような考え方を意識すると理解が深まります。

考え方内容
添え字の範囲0から要素数 - 1までを使う
for文との組み合わせ添え字をカウンタとして使う
条件抽出if文で必要な要素だけを処理する
集計処理合計、平均、最大値、最小値を求める
2次元配列行と列で表形式のデータを扱う
入力値の利用入力に応じて処理範囲を変える

配列は、値を並べておくだけの機能ではありません。for文やif文と組み合わせることで、データを調べる、選ぶ、集計する、表にする、といった処理が書けるようになります。

配列を練習するとプログラム作成力が伸びる

配列の基本は、宣言、初期化、参照です。そこにfor文を組み合わせることで、全要素の表示や集計ができるようになります。さらにif文を加えると、条件に合う要素だけを取り出すこともできます。

2次元配列を使えば、行と列を持つ表形式のデータも扱えます。九九表のような計算結果を保存したり、成績表のようなデータを整理したりする処理に応用できます。

今回の演習で扱った内容は、C言語の配列処理の基本としてとても大切です。まずは小さな配列から始めて、表示、抽出、集計、2次元配列の順に練習していくと、配列の使い方が自然に身についていきます。