C言語のfor文で配列を扱う方法

388, 2022-01-12

目次

C言語のfor文で配列を扱う

C言語ではfor文配列を扱うことができます。
for文と配列を組み合わせると、配列の要素をfor文で出力するなどが可能になります。

for文と配列はC言語のプログラミングでは非常によく使われる機能です
この記事ではfor文で配列を扱う方法について具体的に解説します。

関連記事
C言語のfor文で2ずつカウントする【初心者向け】
C言語のfor文で足し算をして合計を出す
C言語のfor文

配列の要素を出力する

C言語のfor文で配列の要素を参照して出力するには↓のようなコードを書きます。

#include <stdio.h>

int main(void) {
    int ary[] = {1, 2, 3};

    for (int i = 0; i < 3; i += 1) {
        printf("%d\n", ary[i]);
    }

    return 0;
}

上記のコードを実行すると↓の結果になります。

1
2
3

まず配列ですが、これの定義は↓の部分です。

    int ary[] = {1, 2, 3};

aryというint型の配列を定義しています。
配列の各要素は1, 2, 3と初期化しています。
つまりこの配列の要素数は全部で3になります。

次にfor文は↓の部分です。

    for (int i = 0; i < 3; i += 1) {
        printf("%d\n", ary[i]);
    }

このfor文はまずint i = 0;でカウント変数i0で初期化しています。
そしてi < 3;という判定部分では、配列の要素数とカウント変数を比較しています。
この比較はカウント変数が3より下ならtrueに、3以上になったらfalseになります。
更新部分ではi += 1とやってカウント変数iをインクリメントしています。

波カッコ({})の中の処理部分ではprintf()文で配列の要素を出力しています。
配列の要素はint型なので、printf("%d\n", ...);とやって整数を出力しています。
ary[i]とやって配列をカウント変数で参照することで、配列の要素を参照できます。
このfor文は0から2までカウント変数が増加するので、参照される配列の要素は0番目、1番目、2番目になります。

このようにfor文を使うと配列の要素を効率よく出力することができます。

マジックナンバーへの対処

先ほどのfor文ではfor (int i = 0; i < 3; i += 1) {...}と言う風に、for文の判定部分のi < 3マジックナンバー3を使っていました。
このマジックナンバーを使ったfor文は保守性がわるいため、何とかしたいところです。

この場合は↓のようなマクロを定義します。

#define numof(ary) (sizeof ary / sizeof ary[0])

このマクロはaryのバイト数をsizeofで求めて、そのバイト数にary0番目の要素のバイト数を割っています。
たとえばint型の配列で要素数が3の場合を考えてみます。
この配列の全体バイト数はintが4バイトなので4 * 3で12バイトになります。
そして要素1つ分のサイズは4バイトです。
12バイト / 4バイトnumof()の結果は3になります。

このようにこのマクロを使うと配列の要素数を求めることができます。
ただしこのマクロはローカル変数の配列には機能しますが、関数の引数などの配列には機能しないので注意が必要です。

このマクロを使うと先ほどのfor文は↓のように書くことが出来ます。

#include <stdio.h>

#define numof(ary) (sizeof ary / sizeof ary[0])

int main(void) {
    int ary[] = {1, 2, 3};

    for (int i = 0; i < numof(ary); i += 1) {
        printf("%d\n", ary[i]);
    }

    return 0;
}

for文の判定部分がi < numof(ary);になっています。
このようにするとマジックナンバーを無くすことができます。

文字列の配列をfor文で回す

文字列の配列for文で回す方法について解説します。
文字列の配列とはつまりポインタ配列です。
↓のような配列のことです。

const char *ary[] = {
    "Cat",
    "Bird",
    "Dog",
    NULL,
};

このようなポインタ配列は、配列の末尾にNULLポインタを入れておきます。
こうするとfor文でポインタ配列を回す時にNULLポインタを番兵として使うことができます。

#include <stdio.h>

int main(void) {
    const char *ary[] = {
        "Cat",
        "Bird",
        "Dog",
        NULL,
    };

    for (int i = 0; ary[i]; i += 1) {
        printf("%s\n", ary[i]);
    }

    return 0;
}

↑のように文字列の配列(ポインタ配列)をfor文で回すことができます。
for文でカウント変数iをカウントするのは同じですが、判定部分がary[i];になってます。
これは現在のカウント変数の配列の要素がNULLポインタじゃないかチェックしています。
もしNULLポインタだったら、この判定部分の式の結果はfalseになります。
そのためループが終了します。

このようにポインタ配列ではNULLポインタを使うと効率よく要素を参照できます。

二次元配列をfor文で回す

二次元配列をfor文で回したい場合は↓のようにします。

#include <stdio.h>

int main(void) {
    int mat[2][3] = {
        {1, 2, 3},
        {4, 5, 6},
    };

    for (int i = 0; i < 2; i += 1) {
        for (int j = 0; j < 3; j += 1) {
            printf("%d ", mat[i][j]);
        }
        puts("");
    }

    return 0;
}

↑のコードの出力結果は↓になります。

1 2 3
4 5 6

↑のコードでは二次元配列はint mat[2][3] = { ... };がそうです。
この二次元配列は行が2, 列が3の二次元配列になります。

    int mat[2][3] = {
        {1, 2, 3},  // 1行目
        {4, 5, 6},  // 2行目
    };

for文は↓の部分です。

    for (int i = 0; i < 2; i += 1) {
        for (int j = 0; j < 3; j += 1) {
            printf("%d ", mat[i][j]);
        }
        puts("");
    }

外側のfor文で行のカウント変数iをカウントしています。
matの行数は2なのでi < 2;という判定部分になります。
内側のfor文では列のカウント変数jをカウントしています。
matの列数は3なのでj < 3;という判定部分になります。

これらのカウント変数を使うとmatmat[i][j]で参照できます。
参照される添え字は↓になります。

mat[0][0]
mat[0][1]
mat[0][2]
mat[1][0]
mat[1][1]
mat[1][2]
mat[2][0]
mat[2][1]
mat[2][2]

おわりに

今回はC言語のfor文で配列を扱う方法について解説しました。
for文と配列は非常によく使われるC言語の機能です。
覚えておいて損は無いかと思います。

(^ _ ^)

for文で配列を回す

(・ v ・)

相性がイイね

この記事のアンケートを送信する