C言語入門|7章の練習問題

C言語の 7章では「配列と文字列」が本格的に登場し、
大量のデータをまとめて扱うための重要なテクニックを学びました。

「配列」と聞くと難しそうに感じるかもしれませんが、
実は “同じ型の変数が横にずらーっと並んだだけ” の、とてもシンプルな仕組みです。

ここでは練習問題に進む前に、
配列のイメージをしっかりつかんでもらうために、
表を使った図解でわかりやすく解説していきます。

配列とは?(表でイメージ)

配列は、同じ型のデータが連続したメモリ領域に並んでいるものです。
“引き出しが横に並んだ棚”を思い浮かべると理解しやすいです。

配列のイメージ図(一次元配列)

例:int scores[5] = {70, 80, 65, 90, 75};

添え字(index)01234
値(value)7080659075
  • 添え字は 0から始まる
  • scores[0] は 70
  • scores[3] は 90
  • 「scores」という“棚の名前”を使い、必要な引き出しを取り出すイメージ

■ 配列を横から見たメモリイメージ(メモリ連続性)

下の図のように、配列の要素は 必ず隣同士 で並びます。

メモリアドレス内容(scores の値)
0x100070
0x100480
0x100865
0x100C90
0x101075

※int が 4 バイトの場合の例

ポイント

  • 配列は「数字が並ぶ箱」ではなく メモリが連続している塊データ
  • CPU が高速にアクセスできる

二次元配列のイメージ

例:九九の表(int kuku[3][3]; の簡略例)

添え字\列012
0 行123
1 行246
2 行369

“表形式のデータ”を扱うときにとても便利です。

📌 配列を使うメリット(表でまとめ)

メリット説明
ひとまとめで扱える10個の変数をバラバラに用意する必要がなくなる。
ループとの相性が抜群for文と組み合わせると大量データの処理が一瞬
メモリ効率が良い必ず連続領域になるため CPU が高速にアクセスできる。
構造体や文字列にも応用可能配列は C 言語のデータ構造の基盤になる。

📌 取り扱いで特に注意したい点(表)

注意点説明
添え字は 0 から始まるつい “1番目=1” と考えてしまいがち
範囲外アクセスはバグの元scores[5] などは存在しないので要注意
長さの管理は自分で行うC言語には自動で長さチェックする仕組みがない。
文字列は「終端文字」に注意配列としての文字列は最後に '\0' が必要

7章の練習問題

【練習7-1】

次の配列を宣言してください。初期値が指定されているものは同時に初期化してください。

(1)1週間の最高気温を記録する配列 temps(初期値はすべて 0)
(2)方位 N, E, S, W を格納する配列 direction
(3)商品10個の在庫数を格納する配列 stock
(4)九九(1〜9 × 1〜9)の結果を格納する 2次元配列 kuku

【 解答例】

// (1)
int temps[7] = {0};

// (2)
char direction[4] = {'N', 'E', 'S', 'W'};

// (3)
int stock[10];

// (4)
int kuku[9][9];

【解説】

  • {0} は「残り全部も 0 で埋める」という便利な初期化方法。
  • 配列は同じ型の値をまとめるための連続データ領域で、添え字が 0 から 始まる点が重要。
  • 九九のように「表形式」のデータは 2次元配列がぴったり。

【練習7-2】

次の試験結果 45, 72, 68, 90, 81, 54 を配列 scores に格納し、
「最高点」「最低点」「平均点」を求めて画面に表示するプログラムを作成してください。

平均点は 小数点第2位まで 表示してください。

【 解答例】

プロジェクト名:7-13-1 ソースファイル名: sample7-13-1.c

#include <stdio.h>

int main(void)
{
    int scores[6] = {45, 72, 68, 90, 81, 54};
    int max = scores[0];
    int min = scores[0];
    double sum = 0;

    for (int i = 0; i < 6; i++) {
        if (scores[i] > max) max = scores[i];
        if (scores[i] < min) min = scores[i];
        sum += scores[i];
    }

    double average = sum / 6.0;

    printf("最高点:%d\n", max);
    printf("最低点:%d\n", min);
    printf("平均点:%5.2f\n", average);

    return 0;
}

【解説】

  • 合計値を double 型で扱うことで精度を確保。
  • %5.2f は「5桁幅、小数2桁まで」の表示。
  • 「配列+for文」の典型的な使い方で、基礎力として非常に重要。

【 練習7-3】

次の条件を満たすプログラムを作成してください。

  • メンバ「code」(int型)、「character」(char型)を持つ構造体 Alpha を宣言する。
  • 要素数 26 の Alpha 型配列 alphabets を宣言する。
  • 'A'〜'Z' を alphabets に格納し、その ASCII コードも同時に code に格納する。
    ※文字リテラルを直接書かず、ループ変数を使う。
  • 配列の内容を「文字:コード」の形式で表示する。

【 解答例】

プロジェクト名:7-13-2 ソースファイル名: sample7-13-2.c

#include <stdio.h>

struct Alpha {
    int code;
    char character;
};

int main(void)
{
    struct Alpha alphabets[26];

    for (int i = 0; i < 26; i++) {
        alphabets[i].character = 'A' + i;
        alphabets[i].code = (int)alphabets[i].character;
    }

    for (int i = 0; i < 26; i++) {
        printf("%c : %d\n", alphabets[i].character, alphabets[i].code);
    }

    return 0;
}

【解説】

  • 'A' + i という式で A〜Z が作れる
  • ASCII は「文字を数字で表した共通の規格」
  • 構造体+配列+ループの総合技術が学べる良問

【練習7-4】

要素数 12 の int 型配列 sales を用意し、
1〜12月の売上データを適当な値で初期化してください。

さらに、

  • 合計売上
  • 平均売上
  • 最も売れた月(max)
  • 最も売れなかった月(min)

を表示するプログラムを作成してください。

【 解答例】

プロジェクト名:7-13-3 ソースファイル名: sample7-13-3.c

#include <stdio.h>

int main(void)
{
    int sales[12] = {120, 150, 98, 200, 180, 175, 220, 210, 160, 140, 130, 190};

    int max = sales[0], min = sales[0];
    int maxMonth = 1, minMonth = 1;
    double sum = 0;

    for (int i = 0; i < 12; i++) {
        sum += sales[i];
        if (sales[i] > max) {
            max = sales[i];
            maxMonth = i + 1;
        }
        if (sales[i] < min) {
            min = sales[i];
            minMonth = i + 1;
        }
    }

    printf("年間売上合計:%5.1f\n", sum);
    printf("平均売上:%5.1f\n", sum / 12);
    printf("最高売上:%d 月 (%d)\n", maxMonth, max);
    printf("最低売上:%d 月 (%d)\n", minMonth, min);

    return 0;
}

【解説】

  • 月は添え字+1で表せる。
  • min/max と比較処理は多くのプログラムで使われる。
  • 配列を分析する典型例で、実務にも近い。

【練習7-5】

10 人分の身長(cm)を格納した配列 height を使って、

  • 一番背の高い人
  • 一番背の低い人
  • 標準偏差(差の2乗)を用いた簡易計算

を求めて表示するプログラムを作成してください。

【 解答例】

プロジェクト名:7-13-4 ソースファイル名: sample7-13-4.c

#include <stdio.h>
#include <math.h>

int main(void)
{
    double height[10] = {160, 172, 168, 155, 180, 176, 165, 158, 170, 174};

    double max = height[0], min = height[0];
    double sum = 0, ave, variance = 0;

    for (int i = 0; i < 10; i++) {
        sum += height[i];
        if (height[i] > max) max = height[i];
        if (height[i] < min) min = height[i];
    }

    ave = sum / 10;

    for (int i = 0; i < 10; i++) {
        variance += (height[i] - ave) * (height[i] - ave);
    }

    printf("最大身長:%.1f cm\n", max);
    printf("最小身長:%.1f cm\n", min);
    printf("平均身長:%.1f cm\n", ave);
    printf("ばらつき値:%.2f\n", variance / 10);

    return 0;
}

【解説】

  • 標準偏差の概念に触れる良問
  • 2回ループを回す必要がある。
  • math.h の利用も学べる。

【練習7-6】

0〜9 の数字を重複なしで 3 個選び、
配列 answer に格納するプログラムを作ってください。

乱数と while を使って「重複チェックが通るまで繰り返す」処理を実装すること。

【 解答例】

プロジェクト名:7-13-5 ソースファイル名: sample7-13-5.c

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(void)
{
    srand((unsigned)time(NULL));
    int answer[3];
    int count = 0;

    while (count < 3) {
        int num = rand() % 10;
        int duplicate = 0;

        for (int i = 0; i < count; i++) {
            if (answer[i] == num) {
                duplicate = 1;
                break;
            }
        }

        if (!duplicate) {
            answer[count] = num;
            count++;
        }
    }

    printf("答え:%d %d %d\n", answer[0], answer[1], answer[2]);

    return 0;
}

【解説】

  • 「重複しない乱数」はゲーム制作でも常に必要な技術
  • while を使って「条件を満たすまで回す」練習
  • この処理を応用すると、練習7-4 の本格的なゲームにつながる。