C言語プログラミング:do-whileループを使いこなして、よりスマートなコードを書こう


構文

do {
  ループ内の処理;
} while (ループ条件);

解説

  • ループ条件:ループを継続するかどうかを判断する論理式を記述します。
  • while:ループ条件を示すキーワードです。
  • ループ内の処理:ループ内で繰り返し実行される処理を記述します。
  • { }:ループ内の処理を記述する中括弧です。省略することもできますが、可読性を高めるために推奨されます。
  • do:ループの開始を示すキーワードです。

動作

  1. ループ内の処理を実行します。
  2. ループ条件を評価します。
  3. ループ条件が真の場合、1に戻る。
  4. ループ条件が偽の場合、ループを終了します。

whileループとの違い

whileループdo-whileループの主な違いは以下の2点です。

  1. ループ条件の評価タイミング
    • whileループ
      ループの前に評価されます。ループ条件が偽の場合、ループ内の処理は1回も実行されません
    • do-whileループ
      ループの後に評価されます。ループ条件が偽の場合でも、ループ内の処理は少なくとも1回は実行されます。
  2. ループ内の処理の最低実行回数:**
    • whileループ
      ループ条件が真の場合のみ処理が実行されるため、ループ内の処理が0回実行される可能性があります。
    • do-whileループ
      ループ条件が評価される前に処理が実行されるため、ループ内の処理が少なくとも1回は実行されます。

以下のプログラムは、1から10までの整数を順に表示するdo-whileループの例です。

#include <stdio.h>

int main() {
  int i = 1;

  do {
    printf("%d ", i);
    i++;
  } while (i <= 10);

  return 0;
}

出力

1 2 3 4 5 6 7 8 9 10

利点

  • 初期化処理などをループの最初に記述する必要がないため、コードが簡潔になる場合があります。
  • ループ条件がであっても、ループ内の処理を少なくとも1回は実行する必要がある場合に適しています。
  • ループ条件がであっても、ループ内の処理が1回実行されるため、処理効率がwhileループよりも劣る場合があります。

do-whileループは、ループ条件をループの後に評価するため、ループ内の処理が少なくとも1回は必ず実行されるという特徴があります。この特性を活かして、ループ条件がであってもループ内の処理を1回は実行する必要がある場合などに適しています。

一方、ループ条件がであってもループ内の処理が1回実行されるため、処理効率がwhileループよりも劣る場合があります。そのため、ループ条件がであることが確実な場合は、whileループを使用する方が効率的です。

適切なループ構造を選択することは、プログラムの可読性処理効率を向上させるために重要です。



1から10までの整数を逆順に表示

#include <stdio.h>

int main() {
  int i = 10;

  do {
    printf("%d ", i);
    i--;
  } while (i >= 1);

  return 0;
}

出力

10 9 8 7 6 5 4 3 2 1

ユーザーが入力した数値の合計を求める

#include <stdio.h>

int main() {
  int num, sum = 0;

  do {
    printf("数値を入力してください: ");
    scanf("%d", &num);
    sum += num;
  } while (num != 0);

  printf("合計: %d\n", sum);

  return 0;
}

実行例

数値を入力してください: 10
数値を入力してください: 5
数値を入力してください: 2
数値を入力してください: 0
合計: 17

パスワード認証を行う

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

int main() {
  char password[100];

  do {
    printf("パスワードを入力してください: ");
    scanf("%s", password);

    if (strcmp(password, "secret") == 0) {
      printf("ログイン成功!\n");
      break;
    } else {
      printf("パスワードが間違っています。もう一度入力してください。\n");
    }
  } while (1);

  return 0;
}

実行例

パスワードを入力してください: incorrect
パスワードが間違っています。もう一度入力してください。
パスワードを入力してください: another_incorrect_password
パスワードが間違っています。もう一度入力してください。
パスワードを入力してください: secret
ログイン成功!
#include <stdio.h>
#include <stdlib.h>

int main() {
  int num;

  do {
    num = rand() % 100;
    printf("%d ", num);
  } while (num >= 10);

  printf("\n10以下のランダムな数値: %d\n", num);

  return 0;
}

出力例

73 24 9 6 5
10以下のランダムな数値: 5

これらの例は、do-whileループの様々な使用方法を示しています。do-whileループは、様々な状況で使用できる汎用的なループ構造です。



whileループ

whileループは、ループ条件がの場合のみループを継続するループ構造です。do-whileループと異なり、ループ内の処理が0回実行される可能性があります。

利点

  • do-whileループよりも簡潔なコードで記述できる場合があります。
  • ループ条件がであることが確実な場合に効率的です。

欠点

  • ループ条件がの場合、ループ内の処理が1回も実行されない可能性があります。


int main() {
  int i = 1;

  while (i <= 10) {
    printf("%d ", i);
    i++;
  }

  return 0;
}

出力

1 2 3 4 5 6 7 8 9 10

forループ

forループは、ループカウンタを初期化し、ループ条件を満たすまで一定間隔でインクリメントしながらループを継続するループ構造です。do-whileループwhileループよりも、ループの範囲を明確に記述できるという利点があります。

利点

  • ループカウンタを自由に操作できる。
  • ループの範囲を明確に記述できる。

欠点

  • ループ条件が複雑な場合、whileループdo-whileループよりも記述が煩雑になる場合があります。


int main() {
  for (int i = 1; i <= 10; i++) {
    printf("%d ", i);
  }

  return 0;
}

出力

1 2 3 4 5 6 7 8 9 10

goto文

goto文は、プログラムの制御フローを任意の場所にジャンプさせる文です。ループ構造を構成するためにgoto文を使用することはできますが、非構造化プログラミングとなるため、可読性が低くなり、保守が難しくなるという欠点があります。

利点

  • 複雑なループ構造を記述できる。

欠点

  • 保守が難しくなる。
  • 非構造化プログラミングとなり、可読性が低くなる。


int main() {
  int i = 1;

  loop:
    printf("%d ", i);
    i++;

    if (i > 10) {
      goto exit;
    }

    goto loop;

  exit:
    return 0;
}

出力

1 2 3 4 5 6 7 8 9 10

再帰

再帰は、関数を自分自身を呼び出すことでループ構造を構成する手法です。do-whileループwhileループよりもエレガントなコードで記述できる場合があります。

利点

  • エレガントなコードで記述できる。

欠点

  • スタックオーバーフローが発生する可能性があります。
  • 複雑な再帰呼び出しは、理解しにくく、デバッグが難しい場合があります。


void printNumbers(int n) {
  if (n == 0) {
    return;
  }

  printf("%d ", n);
  printNumbers(n - 1);
}

int main() {
  printNumbers(10);

  return 0;
}
10 9 8 7 6 5 4 3 2 1