[C言語のはじめ方] Part6: 制御構文(if, switch, for, while, do-while)

制御構文(if, switch, for, while, do-while)をマスターしよう!

こんにちは!C言語学習の旅へようこそ。前回までに、変数や演算子といった基本的な要素を学びましたね。今回は、プログラムの流れを自在に操るための重要なテクニック、制御構文について学んでいきましょう!

プログラムは通常、上から下へ順番に実行されますが、特定の条件によって処理を変えたり、同じ処理を繰り返し実行したりしたい場面がたくさんあります。そんな時に活躍するのが制御構文です。

C言語には主に以下の制御構文があります。

  • if文: 条件によって処理を分岐させる(もし〜なら…する)
  • switch文: 特定の値によって処理を多岐に分岐させる
  • for文: 決まった回数だけ処理を繰り返す
  • while文: 条件が満たされている間、処理を繰り返す
  • do-while文: 最低1回は処理を実行し、その後条件が満たされている間繰り返す

一つずつ、具体的な使い方を見ていきましょう!


1. if文:条件分岐の基本

if文は、プログラムの中で最もよく使われる制御構文の一つです。「もし〇〇なら、△△する」というように、条件が満たされた(真: true)場合のみ特定の処理を実行します。

基本的な形は次の通りです。

if (条件式) { // 条件式が真 (true) の場合に実行される処理
} 

条件式には、結果が真(0以外)または偽(0)になる式を書きます。比較演算子(<, >, <=, >=, ==, !=)がよく使われます。

例として、点数が60点以上なら「合格」と表示するプログラムを見てみましょう。

#include <stdio.h>
int main(void) { int score = 75; printf("点数: %d点\n", score); if (score >= 60) { printf("合格です!\n"); } printf("処理を終了します。\n"); return 0;
} 
実行結果:
点数: 75点
合格です!
処理を終了します。

この例では、変数scoreが75なので、score >= 60という条件式は真になります。そのため、if文の中括弧{}で囲まれたprintf("合格です!\n");が実行されました。もしscoreが50だったら、「合格です!」は表示されません。

else:条件に合わなかった場合の処理

「もし〇〇なら△△する、そうでなければ□□する」という処理をしたい場合は、elseを使います。

if (条件式) { // 条件式が真 (true) の場合に実行される処理
} else { // 条件式が偽 (false) の場合に実行される処理
} 

先ほどの例に、60点未満の場合「不合格です…」と表示する処理を追加してみましょう。

#include <stdio.h>
int main(void) { int score = 45; // 点数を変更 printf("点数: %d点\n", score); if (score >= 60) { printf("合格です!\n"); } else { printf("不合格です…\n"); } printf("処理を終了します。\n"); return 0;
} 
実行結果:
点数: 45点
不合格です…
処理を終了します。

今度はscoreが45なので、score >= 60は偽になります。そのため、elseブロック内の処理が実行されました。

else if:複数の条件で分岐

さらに多くの条件で処理を分けたい場合は、else ifを使います。「もし条件Aなら処理A、そうでなくもし条件Bなら処理B、そうでなくもし条件Cなら処理C、…、そうでなければ最後の処理」といった流れを作れます。

if (条件式1) { // 条件式1が真の場合の処理
} else if (条件式2) { // 条件式1が偽で、条件式2が真の場合の処理
} else if (条件式3) { // 条件式1も2も偽で、条件式3が真の場合の処理
} else { // すべての条件式が偽の場合の処理
} 

点数に応じて成績を表示する例です。

#include <stdio.h>
int main(void) { int score = 82; printf("点数: %d点\n", score); if (score >= 90) { printf("成績: 優 \n"); } else if (score >= 80) { printf("成績: 良 \n"); } else if (score >= 70) { printf("成績: 可 \n"); } else if (score >= 60) { printf("成績: 合格 \n"); } else { printf("成績: 不合格 \n"); } printf("処理を終了します。\n"); return 0;
} 
実行結果:
点数: 82点
成績: 良
処理を終了します。

else ifは上から順番に評価され、最初に真になった条件の処理が実行されると、残りのelse ifelseは無視されます。この例ではscore >= 90は偽ですが、次のscore >= 80が真になったため、「成績: 良 」が表示され、それ以降の条件はチェックされません。


2. switch文:多分岐処理の選択肢

switch文は、ある変数の値に応じて、処理を分岐させたい場合に便利です。else ifをたくさん連ねるよりも、コードがすっきりすることがあります。特に、メニュー選択のような処理に適しています。

基本的な形は次の通りです。

switch (式) { case 定数1: // 式の値が定数1と一致した場合の処理 break; // switch文を抜ける case 定数2: // 式の値が定数2と一致した場合の処理 break; case 定数3: // 式の値が定数3と一致した場合の処理 break; default: // 省略可能 // どのcaseにも一致しなかった場合の処理 break;
} 
  • : 評価する変数や式(主に整数型や文字型)を指定します。
  • case 定数:: の値が定数と一致した場合に、ここから処理を開始します。定数はリテラル(例: 1, 'A')や定数式である必要があります。
  • break;: これが非常に重要です!breakがないと、一致したcase以降の処理がすべて実行されてしまいます(これを「フォールスルー」と呼びます)。通常は各caseの最後にbreak;を書きます。
  • default:: どのcaseにも一致しなかった場合に実行される処理です。省略可能です。

例として、入力された数字に応じてメッセージを表示するプログラムを見てみましょう。

#include <stdio.h>
int main(void) { int num; printf("好きな数字を入力してください (1, 2, or 3): "); scanf("%d", &num); // キーボードから整数を入力 switch (num) { case 1: printf("1番が好きなんですね!\n"); break; // これがないと case 2 も実行されてしまう! case 2: printf("2番はバランスが良いですね!\n"); break; case 3: printf("3番、ラッキーナンバーかも?\n"); break; default: printf("1, 2, 3 以外が入力されました。\n"); // default の後にも break を書くのが一般的(必須ではない) break; } printf("処理を終了します。\n"); return 0;
} 
実行例 (2を入力した場合):
好きな数字を入力してください (1, 2, or 3): 2
2番はバランスが良いですね!
処理を終了します。

注意: breakの書き忘れ

switch文で最も注意すべき点はbreakの書き忘れです。意図しない動作の原因となるため、各caseの終わりには原則としてbreakを記述しましょう。

3. for文:繰り返し処理の定番

for文は、「〇回繰り返す」のように、繰り返す回数があらかじめ決まっている場合に非常によく使われます。ループ処理の代表格です。

基本的な形は次の通りです。

for (初期化式; 条件式; 変化式) { // 条件式が真 (true) の間、繰り返される処理
} 
  • 初期化式: ループが始まる最初の一度だけ実行されます。ループカウンタとして使う変数を初期化することが多いです(例: int i = 0;)。
  • 条件式: ループを繰り返すかどうかを判定します。この式が真の間、ループ内の処理が実行されます。偽になるとループを終了します(例: i < 10;)。
  • 変化式: ループ内の処理が一回終わるごとに実行されます。ループカウンタの値を更新することが多いです(例: i++)。

例として、1から5までの数字を表示するプログラムを見てみましょう。

#include <stdio.h>
int main(void) { int i; // ループカウンタ変数 printf("ループを開始します。\n"); // i を 1 からスタートし、i が 5 以下の間、i を 1 ずつ増やしながら繰り返す for (i = 1; i <= 5; i++) { printf("i = %d\n", i); } printf("ループが終了しました。\n"); return 0;
} 
実行結果:
ループを開始します。
i = 1
i = 2
i = 3
i = 4
i = 5
ループが終了しました。

このfor文の動作は次のようになります。

  1. 初期化: i = 1; が実行され、iが1になります。
  2. 条件判定: i <= 5; (1 = 5) は真なので、ループ内の処理に進みます。
  3. 処理実行: printf("i = %d\n", i); が実行され、「i = 1」が表示されます。
  4. 変化: i++; が実行され、iが2になります。
  5. 条件判定: i <= 5; (2 = 5) は真なので、ループ内の処理に進みます。
  6. 処理実行: 「i = 2」が表示されます。
  7. 変化: iが3になります。
  8. (同様に i=3, 4, 5 の場合も繰り返す)
  9. 変化: iが6になります。
  10. 条件判定: i <= 5; (6 = 5) は偽なので、ループを終了します。
  11. ループ後のprintf("ループが終了しました。\n");が実行されます。

for文は配列の処理など、多くの場面で活躍します。


4. while文:条件が続く限り繰り返す

while文は、「〇〇の間は△△を繰り返す」というように、特定の条件が満たされている(真である)間、処理を繰り返します。for文と異なり、繰り返す回数が事前に明確でなくても使えます。

基本的な形は次の通りです。

while (条件式) { // 条件式が真 (true) の間、繰り返される処理 // ループ内で条件式に関わる変数を変化させる必要があることが多い
} 

while文は、まず条件式を評価し、真であれば{}内の処理を実行します。処理が終わると、再び条件式を評価し、真であればまた処理を実行…という流れを繰り返します。条件式が偽になった時点でループを終了します。

注意: 無限ループ

while文では、ループ内の処理で条件式がいつか偽になるように変数を変化させることを忘れないでください。さもないと、条件式がずっと真のままになり、ループが永遠に終わらない「無限ループ」に陥ってしまいます。

例として、入力された数値が0になるまで、入力された数値を表示し続けるプログラムを見てみましょう。

#include <stdio.h>
int main(void) { int num; printf("数値を入力してください (0で終了): "); scanf("%d", &num); // 入力された数値 (num) が 0 でない間、ループを続ける while (num != 0) { printf("入力された数値: %d\n", num); // 次の数値を入力してもらう (ここでnumの値が変化する可能性がある) printf("次の数値を入力してください (0で終了): "); scanf("%d", &num); } printf("0が入力されたので終了します。\n"); return 0;
} 
実行例:
数値を入力してください (0で終了): 5
入力された数値: 5
次の数値を入力してください (0で終了): 3
入力された数値: 3
次の数値を入力してください (0で終了): 0
0が入力されたので終了します。

この例では、num != 0 が条件式です。ユーザーが0以外の数値を入力している間はループが続き、0を入力すると条件式が偽となりループを抜けます。ループ内でscanfを使ってnumの値を更新している点がポイントです。


5. do-while文:最低1回は実行する繰り返し

do-while文はwhile文と似ていますが、条件判定をループ処理の後に行う点が異なります。そのため、条件式の結果に関わらず、ループ内の処理が最低でも1回は必ず実行されます

基本的な形は次の通りです。

do { // 最初に必ず1回実行され、その後は条件式が真の間繰り返される処理
} while (条件式); // セミコロンを忘れない! 

最初に{}内の処理を実行し、その後while (条件式)で条件を判定します。条件式が真であれば、再び{}内の処理に戻り、偽であればループを終了します。

例えば、ユーザーにメニューを表示して選択させ、不正な入力の場合は再入力を促すような処理に適しています。

#include <stdio.h>
int main(void) { int choice; do { // まずメニューを表示して入力を促す (最低1回は実行される) printf("\n--- メニュー ---\n"); printf("1: ファイルを開く\n"); printf("2: ファイルを保存する\n"); printf("3: 終了\n"); printf("選択してください (1-3): "); scanf("%d", &choice); // 入力が不正な場合 (1未満または3より大きい場合) はループを続ける } while (choice < 1 || choice > 3); // 条件: 選択が1未満 または 3より大きい printf("\n選択された処理を実行します: %d\n", choice); // ここで choice の値に応じた処理を行う (今回は省略) if (choice == 3) { printf("プログラムを終了します。\n"); } return 0;
} 
実行例 (不正な入力を含む):
— メニュー —
1: ファイルを開く
2: ファイルを保存する
3: 終了
選択してください (1-3): 5
— メニュー —
1: ファイルを開く
2: ファイルを保存する
3: 終了
選択してください (1-3): 0
— メニュー —
1: ファイルを開く
2: ファイルを保存する
3: 終了
選択してください (1-3): 2
選択された処理を実行します: 2

この例では、最初に必ずメニューが表示され、入力が促されます。while (choice < 1 || choice > 3); の部分で、入力されたchoiceが1未満か、または3より大きい場合に条件式が真となり、ループが繰り返されます(メニューが再表示されます)。ユーザーが1, 2, または 3 を入力すると条件式が偽になり、ループを抜けて次の処理に進みます。


まとめ

今回は、プログラムの流れを制御するための重要な構文、if, switch, for, while, do-while を学びました。

  • if文(else, else if): 条件に応じて処理を分岐させる基本。
  • switch文: 特定の値に基づいて多分岐させる場合に便利。breakを忘れずに!
  • for文: 繰り返す回数が決まっている場合に最適。
  • while文: 条件が真である間、繰り返し処理を行う。無限ループに注意!
  • do-while文: 最低1回の実行を保証したい場合に使う繰り返し処理。

これらの制御構文を組み合わせることで、より複雑で実用的なプログラムを作成することができます。例えば、forループの中でif文を使って特定の条件の時だけ処理を行う、といったことが可能です。

最初はどの構文をいつ使えば良いか迷うかもしれませんが、たくさんのコードを読んだり書いたりするうちに、自然と使い分けができるようになります。焦らず、一つ一つの構文に慣れていきましょう!

次回は、データをまとめて扱うための「配列」や、処理を部品化する「関数」について学んでいきます。お楽しみに!

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です