C言語

【C言語】第2章第10回:制御構文を組み合わせた例題と解説

制御構文(if文、while文、for文、switch文など)は、プログラムの動作を柔軟に制御するために不可欠です。この章では、これらの構文を組み合わせた実用的な例を解説し、応用力を高めます。

1. 制御構文を組み合わせる意義

複数の制御構文を組み合わせることで、複雑なロジックを簡潔に記述できます。以下のような状況で特に効果を発揮します:

  • 多段階の条件分岐を含む処理
  • 繰り返し処理と条件分岐を統合
  • 異なる入力に応じた柔軟な応答

2. 基本例:数値ゲーム

以下は、ユーザーが1〜100の範囲で数値を当てるゲームのプログラムです。

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

int main() {
    int target, guess, attempts = 0;

    srand(time(0)); // ランダム数の種を初期化
    target = rand() % 100 + 1; // 1から100までのランダムな数を生成

    printf("Guess the number (between 1 and 100):\n");

    while (1) {
        printf("Enter your guess: ");
        scanf("%d", &guess);
        attempts++;

        if (guess == target) {
            printf("Congratulations! You guessed it in %d attempts.\n", attempts);
            break; // 正解したらループを終了
        } else if (guess < target) {
            printf("Too low. Try again.\n");
        } else {
            printf("Too high. Try again.\n");
        }
    }

    return 0;
}

解説:

  • while (1):無限ループを使用してユーザーの入力を待機。
  • if-else if:入力された値が正解かどうかを判定。
  • break:ユーザーが正解を入力したらループを終了。

3. 応用例:メニュー選択プログラム

ユーザーがメニューから選択を行い、それに応じた処理を実行するプログラムです。

#include <stdio.h>

int main() {
    int choice;

    while (1) {
        printf("\nMenu:\n");
        printf("1. Add numbers\n");
        printf("2. Multiply numbers\n");
        printf("3. Exit\n");
        printf("Enter your choice: ");
        scanf("%d", &choice);

        switch (choice) {
            case 1: {
                int a, b;
                printf("Enter two numbers to add: ");
                scanf("%d %d", &a, &b);
                printf("Result: %d\n", a + b);
                break;
            }
            case 2: {
                int a, b;
                printf("Enter two numbers to multiply: ");
                scanf("%d %d", &a, &b);
                printf("Result: %d\n", a * b);
                break;
            }
            case 3:
                printf("Exiting program.\n");
                return 0;
            default:
                printf("Invalid choice. Please try again.\n");
        }
    }
}

解説:

  • while (1):メニューを繰り返し表示。
  • switch-case:ユーザーの選択に応じた処理を実行。
  • default:無効な選択に対するエラーメッセージを表示。

4. 注意点:ネストの深さを管理

制御構文を組み合わせる際には、以下の点に注意が必要です:

  • ネストが深くなるとコードが読みづらくなるため、関数に分割して簡潔にする。
  • 条件を整理し、冗長な判定を避ける。
  • 変数のスコープを適切に管理し、意図しない動作を防ぐ。

5. 練習問題

以下の課題に挑戦して、制御構文を組み合わせたプログラムの設計を練習してください。

  1. ユーザーに数値を入力させ、偶数か奇数かを判定するメニューを表示するプログラムを作成してください。
  2. 九九の掛け算表を表示し、特定の条件(例:掛け算の結果が偶数の場合)で結果をスキップするプログラムを作成してください。
  3. 入力された文字列が回文かどうかを判定するプログラムを作成してください。

6. 練習問題の解答と解説

問1の解答

#include <stdio.h>

int main() {
    int number;

    while (1) {
        printf("Enter a number (or -1 to exit): ");
        scanf("%d", &number);

        if (number == -1) {
            break; // 終了条件
        }

        if (number % 2 == 0) {
            printf("%d is even.\n", number);
        } else {
            printf("%d is odd.\n", number);
        }
    }

    return 0;
}

問2の解答

#include <stdio.h>

int main() {
    for (int i = 1; i <= 9; i++) {
        for (int j = 1; j <= 9; j++) {
            if ((i * j) % 2 == 0) {
                continue; // 結果が偶数の場合スキップ
            }
            printf("%d x %d = %d\n", i, j, i * j);
        }
    }

    return 0;
}

問3の解答

#include <stdio.h>
#include <string.h>

int main() {
    char str[100], reversed[100];
    int length, isPalindrome = 1;

    printf("Enter a string: ");
    scanf("%s", str);

    length = strlen(str);
    for (int i = 0; i < length; i++) {
        if (str[i] != str[length - i - 1]) {
            isPalindrome = 0; // 回文ではない
            break;
        }
    }

    if (isPalindrome) {
        printf("The string is a palindrome.\n");
    } else {
        printf("The string is not a palindrome.\n");
    }

    return 0;
}

7. まとめ

制御構文を組み合わせることで、複雑な処理を簡潔に記述できます。今回の例題と練習問題を通じて、制御構文を使いこなす力を身につけましょう!