サンプル・プログラム
複利計算
10年ならいいが、これが30年、50年‥‥となると、大きな表計算になってしまう。
こういうときにプログラムを使うと便利だ。
44: //複利計算
45: let deposit = principal; //預金額
46: for (let i = 0; i < period; i++) {
47: deposit *= (1 + rate);
48: }
for (初期値; 繰り返し条件; 繰り返し計算式) {まず初期値を計算する。そして、繰り返し条件が成立する間、ブレース {...} で囲まれたブロック文を実行し、繰り返し計算式を計算する。
処理1;
処理2;
‥‥
}
複利計算のように繰り返しが「回数」で決まる場合、初期値、繰り返し条件、繰り返し計算式にはカウンタが入る。カウンタとしては変数 i を使うのがお作法だ。
通日計算
42: //通日計算
43: for (let i = 1; i <= month; i++) {
44: let mm = 0;
45: //月の大小判定
46: switch (i) {
47: case 1:
48: case 3:
49: case 5:
50: case 7:
51: case 8:
52: case 10:
53: case 12:
54: mm = 31;
55: break;
56: case 4:
57: case 6:
58: case 9:
59: case 11:
60: mm = 30;
61: break;
62: case 2:
63: //うるう年判定
64: if (year % 400 === 0) {
65: mm = 29;
66: } else if (year % 100 === 0) {
67: mm = 28;
68: } else if (year % 4 === 0) {
69: mm = 29;
70: } else {
71: mm = 28;
72: }
73: break;
74: }
75: //当月
76: if (i === month) {
77: current_day += (day - 1);
78: //それ以外
79: } else {
80: current_day += mm;
81: }
82: }
83: //計算結果
ここでは、forループ の中に、「3.2 switch~case文」で紹介した月の大小を求めるため switch~case文と、「3.1 if~else文」で紹介したうるう年を求めるため if~else文を組み込むことで通日を計算している。
再び複利計算
お気づきの方も多いと思うが、ExcelのFV関数を知っていれば、1行で複利計算ができる。
制御文を適切に使うことで、問題が変わった場合に、少しの変更で対応が可能になる。
48: //複利計算
49: let deposit = principal; //預金額
50: for (let i = 0; i < period; i++) {
51: deposit *= (1 + rate);
52: if (deposit > border) break; //計算終了
53: }
forループ で複利計算中をしている最中、預金額 deposit が境界値 border を超えたら break する。
break は「3.2 switch~case文」で紹介したが、これを実行すると処理を中断し、ブロックの外へ制御を移す。つまり、if文を使って預金額 deposit が境界値 border を超えたら、複利計算を中断(ループから脱出)する。
コラム:GOTO文
"for5.html" と同じプログラムをBASICで書くと、次のようになる。
GOTO は break と違って、ブロックからの脱出といった使い方の制約がなく、どこへでもジャンプすることができる。無制限に GOTO を使うとプログラムの流れを追うことが難しくなり、バグの温床となった。
deposit = 10000
For i = 0 to 30
deposit = deposit * 1.011
If deposit > 11000 Then Goto *Disp
next
*Disp
Print deposit
End
こうして「GOTOは使ってはいけない」というお作法が広まったのだが、本来の経緯から言えば、ループからの脱出に用いるなど使用法を制限すればいいのであって、GOTO そのものが悪いわけではない。
さらに言えば、CPUに直接命令を書くことができるアセンブラ言語では、制御文に当たる命令がなく、ほとんどが条件演算とGOTOに相当する jmp命令(プログラムカウンタに代入する)の組み合わせで実現している。つまり、JavaScriptもBASICも、最終的にはGOTOに相当する命令をCPUに送っている。
本シリーズを含め、プログラミングの参考書で「お作法」を見かけたときは、なぜそのお作法ができたのか、経緯まで遡って調べてほしい。そういう手間暇を惜しまないのが、技術者のあるべき姿なので。
さらに、forループの中に if~else文や switch~case文を組み込んだり、break を使って脱出することで応用範囲が広がる。