C言語の基本|if文の基本

ifは、条件が成立したときだけ処理を動かすスイッチ。0と0以外の判定を理解して、条件分岐の基本を身につけよう。

プログラムでは、記述された処理を上から順番に実行するだけでなく、状況に応じて動作を変えることがあります。

たとえば、次のような処理です。

  • 入力された値が正しい場合だけ計算する
  • デバイスの温度が高い場合だけ警告する
  • パスワードが一致した場合だけログインを許可する
  • 在庫がある場合だけ購入処理を続ける
  • エラーが発生した場合だけ処理を中止する

このように、条件の結果によって実行する処理を選ぶ仕組みを選択構造といいます。

C言語では、選択構造を表す代表的な制御文としてifとswitchがあります。

制御文主な役割
if条件式の結果によって処理を実行する
switch式の値によって複数の処理から1つを選ぶ

この記事では、条件分岐の基本となるifについて、条件式、真と偽、ブロック、インデント、比較演算子の使い方を順番に確認します。

ifは条件が真のときだけ処理する

ifは、指定した条件が成立した場合だけ、特定の処理を実行する制御文です。

条件が成立することを真、成立しないことを偽といいます。

ifの処理は、次のように進みます。

  1. 条件式を評価する
  2. 条件式が真ならブロック内を実行する
  3. 条件式が偽ならブロック内を実行しない
  4. ifの後ろにある処理へ進む

ifだけを使った条件分岐では、条件が偽の場合に実行する専用の処理はありません。ブロックを飛ばし、その後ろにある処理へ進みます。

ifの基本構文

ifは、次の形式で記述します。

if (条件式) {
    文;
}

各部分には、次の役割があります。

記述役割
if条件によって処理を選ぶ制御文
条件式真か偽かを判定する式
( )条件式を囲む丸括弧
{ }条件が真の場合に実行する範囲
条件が真の場合に実行する処理

ifの後ろには丸括弧が必要です。丸括弧の中へ条件式を記述します。

条件式の後ろにセミコロンは付けません。実行する文の末尾には、通常どおりセミコロンを付けます。

図1:if文で処理を実行するか選ぶ流れ

この図から分かること

デバイス温度が80度以上なら条件は真になり、高温警告を表示します。

80度未満なら条件は偽になるため、高温警告の処理を通りません。そのまま入力された温度を表示する処理へ進みます。

条件が真の場合も偽の場合も、ifが終わった後は共通の処理へ進みます。ifは、条件が成立したときだけ追加の処理を実行したい場合に適しています。

C言語では0が偽、0以外が真になる

C言語の条件判定では、式の値によって真と偽が決まります。

条件式の値判定
0
1
-1
25
-100

0だけが偽です。正の値でも負の値でも、0以外はすべて真として扱われます。

たとえば、次の条件は偽になるため、ブロック内の処理は実行されません。

if (0) {
    printf("この文は実行されません。\n");
}

次の条件は1なので真になり、ブロック内が実行されます。

if (1) {
    printf("この文は実行されます。\n");
}

負の値も0以外なので真です。

if (-5) {
    printf("負の値でも0以外なら真です。\n");
}

条件式に直接数値を書くことは多くありませんが、0と0以外の判定規則を理解するために役立ちます。

図2:0と0以外による真偽の判定

この図から分かること

C言語では、条件式の値が0の場合だけ偽になります。

1だけが真になるわけではありません。-1、25、-100など、0以外の値はすべて真として扱われます。

比較演算子や論理演算子を使った条件式は、条件が成立すれば1、成立しなければ0になります。その結果を使って、ifのブロックを実行するか判断します。

比較演算子で条件式を作る

実際のifでは、変数の値を比較して条件式を作ることが多くなります。

比較演算子意味条件式の例
==等しいstatus == 0
!=等しくないstatus != 0
<より小さいtemperature < 0
<=以下count <= 10
>より大きいspeed > 100
>=以上temperature >= 80

比較演算子による式は、比較結果に応じて1または0になります。

たとえば、device_temperatureの値が86の場合、device_temperature >= 80は成立するため、式の結果は1です。

device_temperatureの値が62の場合は成立しないため、式の結果は0です。

device_temperaturedevice_temperature >= 80判定
861
801
790
620

=は以上を表すため、境界値の80も真になります。

80より大きい場合だけ真にしたいなら、>を使います。条件を作るときは、境界値を含めるかどうかを確認することが大切です。

論理演算子で条件を組み合わせる

複数の条件を組み合わせる場合は、論理演算子を使います。

論理演算子意味真になる条件
&&かつ両方の条件が真
||またはどちらか一方以上が真
!否定条件が偽

たとえば、温度が0度以上80度未満であることを判定する場合は、2つの条件を&&で組み合わせます。

if (temperature >= 0 && temperature < 80) {
    printf("温度は通常範囲です。\n");
}

temperature >= 0とtemperature < 80の両方が真の場合だけ、ブロック内が実行されます。

どちらか一方の条件が成立すればよい場合は、||を使います。

!は条件の真と偽を反転します。真の条件に!を付けると偽になり、偽の条件に!を付けると真になります。

波括弧はifで実行する範囲を表す

波括弧で囲まれた範囲をブロックといいます。

if (条件式) {
    文1;
    文2;
    文3;
}

条件が真になると、ブロック内にある文1、文2、文3が上から順番に実行されます。

条件が偽なら、3つの文すべてが実行されません。

ifの中に書く文が1つだけの場合は、波括弧を省略できます。

if (条件式)
    文;

ただし、初心者のうちは文が1つでも波括弧を付けると安全です。

後から処理を追加した場合でも、ifによって制御される範囲を間違えにくくなるからです。

インデントで処理の範囲を読みやすくする

ifのブロック内は、行の先頭を字下げして記述します。この字下げをインデントといいます。

if (device_temperature >= 80) {
    printf("高温を検出しました。\n");
    printf("デバイスの状態を確認してください。\n");
}

C言語のコンパイラは、基本的にインデントだけを見て処理範囲を判断するわけではありません。処理範囲は波括弧によって決まります。

それでもインデントは大切です。ブロックの内側と外側が見分けやすくなり、条件が真の場合にどの文が実行されるのかを読み取りやすくなります。

波括弧とインデントを組み合わせて、制御される範囲を見た目から判断できるようにします。

ifを使ったプログラム

ここでは、入力されたデバイス温度が80度以上の場合だけ、高温警告を表示します。

デバイス温度が80度以上なら警告を表示するプログラム

ファイル名:8_1_1.c

#include <stdio.h>

int main(void)
{
    int device_temperature;

    printf("デバイス温度を入力してください > ");
    scanf("%d", &device_temperature);

    /* 80度以上の場合だけ高温警告を表示する */
    if (device_temperature >= 80) {
        printf("警告: デバイスが高温です。\n");
        printf("冷却状態を確認してください。\n");
    }

    printf("入力された温度は%d度です。\n", device_temperature);

    return 0;
}
実行結果の例

86を入力した場合は、条件が真になるため、高温警告が表示されます。

デバイス温度を入力してください > 86
警告: デバイスが高温です。
冷却状態を確認してください。
入力された温度は86度です。

62を入力した場合は、条件が偽になるため、高温警告は表示されません。

デバイス温度を入力してください > 62
入力された温度は62度です。
プログラムの詳しい解説

device_temperatureは、入力されたデバイス温度を保存するint型の変数です。

記述役割
int device_temperature;デバイス温度を保存する変数を宣言する
scanf("%d", &device_temperature);入力された整数を変数へ保存する
if (device_temperature >= 80)温度が80度以上か判定する
printf("警告: デバイスが高温です。\n");条件が真の場合に警告を表示する
printf("冷却状態を確認してください。\n");条件が真の場合に確認内容を表示する
printf("入力された温度は%d度です。\n", device_temperature);ifの判定後に温度を表示する
return 0;main関数を正常終了する

最初にscanfで整数を読み取り、device_temperatureへ保存します。

次に、device_temperature >= 80を評価します。

86を入力した場合、86は80以上なので条件式の結果は1です。条件が真になるため、波括弧内にある2つのprintfが実行されます。

62を入力した場合、62は80以上ではないため条件式の結果は0です。条件が偽になるので、波括弧内の処理をすべて飛ばします。

最後の温度表示はifの波括弧の外側にあります。そのため、条件が真でも偽でも必ず実行されます。

ifの内側と外側を区別する

プログラムの各処理は、次のように分けられます。

処理条件が真条件が偽
高温警告を表示する実行する実行しない
冷却状態の確認を促す実行する実行しない
入力された温度を表示する実行する実行する
return 0で終了する実行する実行する

波括弧内の処理だけがifの条件によって制御されます。

波括弧の外側にある温度表示とreturn 0は、ifの条件に関係なく実行されます。

==と=の違いに注意する

ifの条件式で特に間違えやすいのが、==と=の使い分けです。

演算子役割記述例
==左右の値が等しいか比較するn == 0
=右側の値を左側の変数へ代入するn = 0

nが0と等しいか調べる場合は、==を使います。

if (n == 0) {
    printf("nは0です。\n");
}

次の記述は比較ではありません。

if (n = 0) {
    printf("nは0です。\n");
}

n = 0では、nへ0を代入します。代入式全体の値も0になるため、ifの条件は偽になります。

この記述は文法上の誤りにならず、コンパイルできてしまう場合があります。コンパイラによっては警告が表示されますが、期待した判定にはなりません。

図3:==による比較と=による代入の違い

この図から分かること

n == 0は、nと0が等しいかを比較します。nが0なら1、0以外なら0という結果になります。

n = 0は、nへ0を代入する処理です。比較は行っていません。代入式の値が0になるため、ifの条件は偽になります。

見た目は似ていますが、処理内容はまったく異なります。ifの条件式に=がある場合は、比較ではなく代入になっていないか確認することが大切です。

代入式を条件に書いた場合の動き

代入式は、代入した値そのものを式の値として持ちます。

そのため、次の条件ではnへ5を代入し、代入式の値も5になります。

if (n = 5) {
    printf("この処理は実行されます。\n");
}

5は0以外なので、条件は真です。

一方、n = 0では代入式の値が0になるため、条件は偽です。

条件式nへ代入される値条件の判定
n = 00
n = 11
n = -1-1
n = 100100

このような記述は読み間違いや不具合の原因になりやすいため、値が等しいかを判定するときは==を使用します。

if文を書くときの確認ポイント

ifを書いた後は、次の点を確認すると間違いを見つけやすくなります。

  • 条件式を丸括弧で囲んでいるか
  • 条件式の後ろへ不要なセミコロンを付けていないか
  • 等しいか比較するときに==を使っているか
  • =による代入を誤って書いていないか
  • 境界値を条件に含めるか確認したか
  • ifで実行する範囲を波括弧で囲んでいるか
  • ブロック内をインデントしているか
  • 条件が偽の場合にどの処理へ進むか確認したか

特に、条件式の直後にセミコロンを付けないように注意します。

if (device_temperature >= 80); {
    printf("警告を表示します。\n");
}

この記述では、ifが制御する文がセミコロンだけになってしまいます。その後ろのブロックはifと関係なく実行されます。

条件式の後ろにはそのまま波括弧を置きます。

if (device_temperature >= 80) {
    printf("警告を表示します。\n");
}

条件式、波括弧、インデントを整えて記述すると、ifによって実行される範囲を読み取りやすくなります。