3.1 if~else文

(1/1)
if~else文
JavaScript を含むプログラミング言語には制御という仕組みが備わっており、条件によって計算式を切り換えたり、同じ計算式を繰り返し実行することができる。
制御を活用することで、Excel関数だけでは実現できなかった、さまざまな処理が実現できるようになる。
まず、if~else 文の使い方から学んでゆくことにしよう。あわせて、JavaScript の文とブロック文について説明する。プログラムの内容も、少しずつ実用的なものにステップアップしてゆく。

目次

サンプル・プログラム

4年に一度のうるう年

4 年に一度のうるう年――入力した西暦年がうるう年かどうかを判定するプログラムが "if_else1.html" である。

0019: <script>
0020: /**
0021:  * 判定と画面表示
0022: */
0023: function if_else1() {
0024:     //変数宣言
0025:     var year = document.getElementById('year').value; //西暦年
0026:     year = parseInt(year, 10);                           //10進整数化
0027: 
0028:     //うるう年判定(間違いがある)
0029:     var ret = '平年'
0030:     if (year % 4 == 0) {
0031:         ret = 'うるう年';
0032:     }
0033: 
0034:     //結果を表示する
0035:     document.getElementById('ret').innerHTML = ret;
0036: }
0037: </script>

これまで何度か出てきた if 文を使って、「4 年に一度」の判定をプログラムに実装した。
if 文if (式) のように用い、式が true のとき、それに続くブロック {...} で囲まれた中身)を実行する。

このプログラムでは、まず、判定結果を格納する String 型変数 ret に '平年' を代入しておく。
次に、if 文を使い、西暦年が格納された Number 型変数 year の 4 の剰余を計算し、計算結果が 0 でない(4 で割り切れる)場合は、変数 ret に 'うるう年' を代入する。
最後に、変数 ret の内容を表示する。

正確なうるう年判定

「4 年に一度、うるう年」というのは、じつは不正確である。
現在の西暦であるグレゴリオ暦で、うるう年は次のように定義されている。
  1. 4 で割り切れる年はうるう年である。
  2. ただし、100 で割り切れる年は平年である。
  3. ただし、400 で割り切れる年はうるう年である。
西暦 2000 年は 400 で割り切れたので、うるう年だった。西暦 2100 年は 100 で割り切れるので、平年である。

0019: <script>
0020: /**
0021:  * 判定と画面表示
0022: */
0023: function if_else2() {
0024:     //変数宣言
0025:     var year = document.getElementById('year').value; //西暦年
0026:     year = parseInt(year, 10);                           //10進整数化
0027:     var ret;
0028: 
0029:     //うるう年判定(正確なもの)
0030:     if (year % 400 == 0) {
0031:         ret = 'うるう年';
0032:     } else if (year % 100 == 0) {
0033:         ret = '平年';
0034:     } else if (year % 4 == 0) {
0035:         ret = 'うるう年';
0036:     } else {
0037:         ret = '平年';
0038:     }
0039: 
0040:     //結果を表示する
0041:     document.getElementById('ret').innerHTML = ret;
0042: }
0043: </script>

これをプログラムにしたのが "if_else2.html" である。
if~else 文は次のようにして使う。
if (式 1) {
    ブロック 1
} else if (式 2) {
    ブロック 2
} else (式 3) {
    ブロック 3
}
  1. もし式 1 が true ならブロック 1 を実行する。
  2. 式 1 が false であり、式 2 が true ならブロック 2 を実行する
  3. 式 1,式 2 がともに false であり、式 3 が true ならブロック 3 を実行する。
式 2 ・ブロック 2 は 2 つ以上書くことができる(必要がなければ省略できる)が、最初の if 文と最後の else 文は各々1 つずつである。

ここで if~else 文 の順序に気をつけよう。
if (year % 4) を先頭に持ってくると、西暦 2100 年もうるう年になってしまう。
まず、グレゴリオ暦の定義を次のように並べ替える必要がある。
  1. もし西暦年を 400 で割り切れれば、うるう年である。
  2. そうでなければ、西暦年を 100 で割り切れれば、平年である。
  3. そうでなければ、西暦年を 4 で割り切れれば、うるう年である。
  4. そうでなければ、平年である
フロー図にすると下図のようになる。
うるう年の判定
うるう年の判定

式とブロック文

JavaScript では命令を文(statement)と呼び、セミコロン ; で区切る。
ret = 'うるう年';
複数の文をまとめてブレース {...} で区切ったものをブロック文と呼ぶ。
if~else 文 は、条件によって、それに続くブロック文を実行するか否かを制御していると言える。

なお、"if_else2.html" のようにブロック文の中の式が 1 つしかない場合、ブレース {...} を省略して次のように書くこともできる。
if (year % 400 == 0)      ret = 'うるう年';
else if (year % 100 == 0) ret = '平年';
else if (year % 4 == 0)   ret = 'うるう年';
else                      ret = '平年';
しかし、あとでプログラムを修正・改変するときに式が増えるといけないので、最初からブレース {...} で囲んでおいた方がメンテナンス性は高まる。
2.1 変数と定数 - グローバル変数とローカル変数」において、let 宣言した変数は、宣言したブロック内(ブロックスコープ)で通用するローカル変数になると説明した。
実用で使うことはあまりないが、制御を伴わないブロック文を使って、この作用を確認しておこう。

0019: <script>
0020: //ページのロード時に実行
0021: window.onload = function() {
0022:     let i = 1;                   //変数宣言・その1
0023:     {
0024:         let i = 2;               //変数宣言・その2
0025:         {
0026:             let i = 3;           //変数宣言・その3
0027:             document.getElementById('let1').innerHTML = i;
0028:         }
0029:         document.getElementById('let2').innerHTML = i;
0030:     }
0031:     document.getElementById('let3').innerHTML = i;
0032: }
0033: </script>

ローカル変数 i を 3 つ宣言しているが、各々の i は、お互いに影響を及ぼさないことがわかる。
ブロック文の中でのみ必要となる作業用変数は、ブロック文の中で let 宣言 して使うといい。

コラム:ExcelのIF関数、他言語の制御文、フロー図

Excelアイコン
Excel にも IF関数が備わっている。
うるう年の判定は、=IF(MOD(A1,400)=0,"うるう年",IF(MOD(A1,100)=0,"平年",IF(MOD(A1,4)=0,"うるう年","平年"))) とすることで実現はできるが、かなり読みにくくなってしまう。JavaScript のように複数行にわたって書くことができるブロック文を制御する方が、読みやすい。
Python で "if_else2.html" を書くと "if_else3.py" 次のようになる。Python ではブロック文をインデントで表す文法になっている。

0014: # うるう年判定(正確なもの)
0015: if year % 400 == 0:
0016:     ret = 'うるう年'
0017: elif year % 100 == 0:
0018:     ret = '平年'
0019: elif year % 4 == 0:
0020:     ret = 'うるう年'
0021: else:
0022:     ret = '平年'
0023: 

PHP の実装例は「PHP で閏年(うるう年)かどうか判定する」をご覧いただきたい。
他の言語も、おおむね JavaScript と書き方は似ている。
制御の流れを表すのに、よくフロー図(流れ図、フローチャート)を使う。本文中でも紹介した。
1.3 四則計算と変数」のコラムで紹介したプログラミング電卓付属の「プログラム・ライブラリ」にもフロー図が掲載されており、とても参考になった。
プログラミングに慣れるまでは、手間を惜しまず、自力でフロー図を書くことをお勧めする。

また、プログラミングに慣れた方でも、プログラムをフロー図にして見直すことで、条件式を正規化することなどして、制御の流れをシンプルにすることができる場合がある。
短くシンプルなプログラムほどバグが少ない。一度、自作プログラムを見直してみてはいかがだろうか。

参考サイト

(この項おわり)
header