入出力と条件分岐

目標

ここではプログラムの流れを条件によって変える、条件分岐について学ぶ。
条件分岐はプログラミングにおいて、基本的な要素の1つである。
また、初歩的なプログラムへの入出力インターフェイスとしてalert()及びprompt()、乱数を発生させるためのMath.random()について学ぶ。

  • 正しくprompt()関数を使い、変数に値を入力することができる。
  • 正しくalert()関数を使い、変数も使いながらメッセージを表示することができる。
  • 乱数を使ったプログラムを作成することができる。
  • 正しく単体の条件式が書ける。
  • 論理演算子を用いて複数の条件式を結合することができる。
  • if文の挙動を理解することができる。if文を正しく書くことができる。
  • if-else文の挙動を理解することができる。if-else文を正しく書くことができる。
  • else if節の挙動を理解することができる。else-if節を正しく書くことができる。
  • switch文の挙動を理解することができる。switch文を正しく書くことができる。

alert()とprompt()

プログラムにおいて、ユーザからの入力を得たり、ユーザに対してメッセージを発したりすることは頻繁に行われる。
ここでは、ブラウザとJavaScriptを使った一番簡単な入力と出力の方法であるprompt()とalert()について紹介する。

prompt()

prompt()関数は、ポップアップによってユーザからの入力を促し、入力値を返す関数である。
prompt()関数はカッコの中に値を1つ入れることができ(「引数を1つとる」と表現する)、その値をメッセージとしてポップアップで表示する。
また、同時に入力用のエリアが表示され、そこに値を入力できる。
入力した値は、関数が返す値となる。
ここで値は文字列として返されるので、数字を入力するような場合には注意が必要である。

次の例では、値を入力するためのポップアップを「あなたの名前は?」というメッセージと共に表示し、入力を促す。
入力された値は、変数yournameに格納される。

...
var yourname = prompt("あなたの名前は?");
...

alert()

alert()関数は、ポップアップによってメッセージを表示するための関数である。
alert()関数は引数を1つとり、その値をメッセージとしてポップアップで表示する。
実際の使い方の例を下記に示す。

...
alert("Hello World!");
...

この例では、文字列リテラルで表現された文字列を単純にポップアップとして表示させている。
一方で、alert()の括弧の中には式を書くこともできる。
式を書くとその評価された値がポップアップとして表示される。

...
var yourname = "taro"; 
...
alert("Hello " + yourname);
...

prompt()とalert()を使った例

次の例は、prompt()alert()を使った例である。
この例では、始めの行で名前を入力させ、入力した名前を変数yournameに格納している。
その上で、名前に続けて「さん、こんにちは」というメッセージをポップアップで表示している。

...
var yourname = prompt("あなたのお名前は?")
alert(yourname + "さん、こんにちは");
...

上記のプログラムが実際に動作する例を次に示す。
ボタンを押してみて欲しい。

さて、次のプログラムを見て欲しい。
このプログラムはどのように動作するであろうか。

...
var num1 = prompt("1つ目の値を入力してください。");
var num2 = prompt("2つ目の値を入力してください。");
alert(num1 + num2);
...

おそらく意図としては、数値を2つ入力してもらい、それぞれ変数num1と変数num2に格納し、その和を表示したいのであろう。
しかし、実際にはそのようにはならない。
実際に動作するボタンを下記に示すので、試してみて欲しい。

実際にやってみて気づくと思うが、入力した2つの値は数値ではなく文字列として扱われてしまっているため、演算子+が文字列同士の足し算、つまり文字列の連結として解釈されてしまっている。
数値の足し算がしたい場合には、文字列を数値に変換する必要がある。
Number()を使って次のようにすると、想定どおりに動作する。

...
var str1 = prompt("1つ目の値を入力してください。");
var str2 = prompt("2つ目の値を入力してください。");
var num1 = Number(str1);
var num2 = Number(str2);
alert(num1 + num2);
...

動作例を次に示す。

乱数

乱数とは

プログラムは、コンピュータに行わせる処理を記述するものである。
基本的には、何らかの条件によって動作を変えたり、繰り返し同じ処理をさせたりすることを記述することによって、プログラム動作が決まる。
しかし、アルゴリズムの中には、モンテカルロ法のように無作為に選択された値(乱数)を必要とするものがある。
多くのプログラミング言語は、このような乱数を発生させるための機能を有している。

Math.random()

JavaScriptにおいて乱数を発生させるためには、Math.random()を用いる。
Math.random()は、Mathオブジェクトのrandom()メソッド呼び出しであるが、Mathオブジェクトについては別の回で説明する。

Math.random()は、呼び出されると、0以上1未満の数を返す。
どのような値が返ってくるかはその時々によって、異なったものとなる。

例えば次のプログラムを見て欲しい。
このプログラムでは、Math.random()を呼び出してその返り値を変数numに代入し、次の行でその値を表示している。
動作例のボタンを何度か押してみて欲しい。
押すたびに異なった値が表示されることがわかるだろう。

var num = Math.random();
alert("乱数の値は" + num + "でした。")

条件分岐の概要

プログラムを書いていると、入力された値などによってプログラムの動作を変えたくなることがある。
このような機能を実現するのが条件分岐と呼ばれるものである。
JavaScriptでは、条件分岐のためにif文とswitch文が用意されている。

条件式

比較演算

条件によってプログラムの動作を変えるためには、まず条件を記述する方法を覚える必要がある。
まずは、条件の記述方法についてみてこう。

多くのプログラミング言語には、ある式が成立する(真、true)か否(偽、false)かを返す種類の演算がある。
これが条件を記述する方法である。
つまり、条件を記述するためにも演算子を使った式が使われる。

まずは、比較演算子について説明する。
比較演算子はその名の通り、演算子の左右の値を比べて、式が成立するかどうかを判断する為の演算子である。
比較演算子には次のようなものがある。

演算子 意味 使用例
== 等値演算。左右の値が同じであるかを判断する。同じ場合には真、そうでない場合には偽を返す。 a == b、sum == 100
!= 不等値演算。左右の値が同じであるかを判断する。異なる場合には真、そうでない場合には偽を返す。 a != b、sum != 100
< 左の値が右の値より小さいかどうかを判断する。小さい場合には真、そうでない場合には偽を返す。 a < b、sum < 100
> 左の値が右の値より大きいかどうかを判断する。大きい場合には真、そうでない場合には偽を返す。 a > b、sum > 100
<= 左の値が右の値以下かどうかを判断する。以下の場合には真、そうでない場合には偽を返す。 a <= b、sum <= 100
>= 左の値が右の値以上かどうかを判断する。以上の場合には真、そうでない場合には偽を返す。 a >= b、sum >= 100

文字列の比較

文字列にも比較演算子を使う事ができる。
この場合は少し注意が必要である。
文字列の大小を比較する場合にはアルファベット順で比較される。
よって、「"3" < "5"」や「"12" < "3"」、「"abc" < "def"」はどれも真になる。
また、日本語の場合は少し複雑である。
コンピュータの内部では、文字は文字コード(JISやEUC、Unicodeといった複数のコードが存在しています)という番号によって表現されている。
文字は、この文字コードの順番によって大小決まる。
このため、あいうえお順にはならない事に気をつける必要がある。

論理演算子

より複雑な条件を記述するためには、幾つかの条件を組み合わせる必要がある。
例えば、ある数字numが3より大きくて10より小さいという条件を記述したい場合、「3 < num」と「num < 10」という二つの条件を満たさなければならない。
このような場合に、式を組み合わせるために論理演算子と呼ばれるものがある。
下記に論理演算子を挙げる。

演算子 意味 使用例 使用例の意味
&& 論理積。and演算。左右とも真の場合に真となる。 3 < num && num < 10 numが3より大きく、10より小さい
|| 論理和。or演算。左右のどちらか、あるいは両方が真の場合に真となる。 num < 3 || 10 < num numが3より小さいか、10より大きい
! 否定。not演算。評価する値が真の場合は偽を、偽の場合は真を返す。 !(num < 3) numが3より小さくない

ある数字numが3より大きくて10より小さいという条件を記述したい場合、上の論理積を使って「3 < num && num < 10」と書く。
3 < num < 10」の様には書くことはできないので、注意が必要である。

和差積商などの算術演算に優先順位があったように、論理演算にも優先順位がある。
論理演算の優先順位は優先順位が高い順に「!」、「&&」、「||」になっている。

論理演算にはいろいろな特徴がある。
例えば、否定の否定は肯定である。
論理演算を使うと「[比較演算]」は「!![比較演算]」と同じになる。
「以下」というのは「より大きいではない」ということである。
ゆえに「a<=b」は「!(a>b)」である。
また、論理演算には「ド・モルガンの法則」と呼ばれる有名な法則もある。
この中では、「!([比較演算1]&&[比較演算2])」は「![比較演算1]||![比較演算2]」と同じだということを保証している。
また同様に、「!([比較演算1]||[比較演算2])」は「![比較演算1]&&![比較演算2]」と同じである。

if文、if-else文

基本的なif文

一番基本的なif文の使い方は、ある条件が成り立つ時のみプログラムの一部分を実行するというものである。
次の図に示すのはフローチャートと呼ばれるもので、プログラムの流れを表す為の手法の一つである。
この図では、if文の流れを表している。
if文では、ある条件が成り立ったときのみ処理を行い、成り立たない場合にはなにもしない、というのが一番基本的な書き方である。

基本的なif文の動作のフローチャート
基本的なif文の動作

上図のような動作をするif文は次のように表記する。
if文の条件の括弧の中には、上で説明したような比較演算子や論理演算子を組み合わせて記述した条件式を記載する。
もし、その条件式が真の値を返すようであれば中括弧で囲まれた部分が実行される。
条件式が成り立たない場合、すなわち偽となるような場合には中括弧の中は実行されることなく、次の命令に進んでいく。

if (条件) {
  /*
   *  条件が成立する場合のみ実行される処理ブロック
   */
}

if文のelse節

上の基本的なif文では、条件が成立したときのみ中括弧でくくられたブロックが実行された。
しかし、いろいろなプログラムを書いていると、条件が成立する場合には処理1を、成立しなかった場合には処理2を実行したいといったことがある。
論理演算子!を使って逆の条件文を書き、処理2を実行するということもできるが、あまり賢い方法とは思えない。

このようなニーズを満たすために、JavaScriptのif文にはelse節が書けるようになっている。
else節を使う場合の記法は下記のとおりである。

if (条件) {
  /*
   *  条件が成立する場合のみ実行される処理ブロック
   */
} else {
  /*
   *  条件が成立しない場合のみ実行される処理ブロック
   */
}

フローチャートで示すと、下図のようになる。

else節付きif文の動作のフローチャート
else節付きif文の動作

else if

if文を使って更に条件を細かく指定することもできる。
「○○の時は○○○、そうでなく△△の時は△△△、そうでもなく□□の時は□□□、そうでもなく××の時は×××を実行する」といった具合である。
このような条件分岐を記述するためには下記のようにする。
このとき、上から順番に条件を確認していき、始めに当てはまったもののみが実行される。
もし、ある条件1(例: num < 10)が別の条件2(例: num < 100)にすっぽり当てはまる場合、条件1の方を先に書かないと条件1が実行されることは決してない。

if (条件1) {
  /*
   *  条件1が成立する場合のみ実行される処理ブロック
   */
} else if (条件2) {
  /*
   *  条件1が成立せず、条件2が成立する場合のみ実行される処理ブロック
   */
} else if (条件3) {
  /*
   *  条件1〜条件2が成立せず、条件3が成立する場合のみ実行される処理ブロック
   */
...
} else if (条件n) {
  /*
   *  条件1〜条件n-1が成立せず、条件nが成立する場合のみ実行される処理ブロック
   */
}

else ifは幾つつなげても構いまわない。
また、最後に「どの条件にも合致しなかった場合には○○を実行する」という部分を入れたい場合は次のようにする。

if (条件1) {
  /*
   *  条件1が成立する場合のみ実行される処理ブロック
   */
} else if (条件2) {
  /*
   *  条件1が成立せず、条件2が成立する場合のみ実行される処理ブロック
   */
} else if (条件3) {
  /*
   *  条件1〜条件2が成立せず、条件3が成立する場合のみ実行される処理ブロック
   */
...
} else if (条件n) {
  /*
   *  条件1〜条件n-1が成立せず、条件nが成立する場合のみ実行される処理ブロック
   */
} else {
   /*
    *  どの条件にも当てはまらない場合のみ実行される処理ブロック
    */
}

if文を使ったプログラムの例

では、if文を使った実際のプログラムの例を見てみよう。
下記のプログラムを見て欲しい。
HTML部分でボタンを押すと関数に飛ぶ部分は既出である。
JavaScriptにおいては、2行目でユーザからの入力を促し、その値を変数strに格納している。
ここで変数strに格納される値は文字列として扱われるため、次の行でNumber()を使って数値に変換し、改めて変数numに格納している。
その上で、5行目からif文を使って分岐を行っている。
5行目では、フォームに入力された値numを2で割り余りが0かどうかを調べている。
つまり、numが2の倍数かどうかを調べている。
もし、2の倍数の場合はその直後のブロックの中を実行する。
つまり、「2の倍数です。」というメッセージを表示する。
もし2の倍数でなかった場合は、8行目のelse ifへ飛ぶ。
ここでは、numが3の倍数かどうかを調べている。
3の倍数の場合には、2の倍数の時と同様にその直後のブロックを実行し、「3の倍数です。」というメッセージを表示する。
2の倍数でも3の倍数でもない場合は、最後のelse節に飛び、「2の倍数でも、3の倍数でもありません。」というメッセージを表示する。

HTML部分
<button onclick="iftest()">if文を使った例</button>
JavaScript部分
function iftest() {
  var str = prompt("数値を入力してください。");
  var num = Number(str);
 
  if (num % 2 == 0) {  
    // 2の倍数
    alert("2の倍数です。");
  } else if (num % 3 == 0) {  
    // 3の倍数
    alert("3の倍数です。");
  } else {
    // 上記以外なら
    alert("2の倍数でも、3の倍数でもありません。");
  }
}


上記のプログラムにおいて、「6」や「12」など、2の倍数でも3の倍数でもある数値を入力するとどうなるであろうか?
「2の倍数です。」と「3の倍数です。」の両方が表示されるであろうか。
プログラムは基本的に上から下にむけて実行されることを思い出して欲しい。
「6」や「12」が入力された場合には、まず5行目のif文で評価される。
「6」や「12」は2の倍数なので、このif文の条件式が成立し、「2の倍数です。」というメッセージが表示される。
一度条件に合致してしまったので、それ以降のelse ifやelseは飛ばされる。
よって、「6」や「12」など、2の倍数でも3の倍数でもある数値が入力された場合には「2の倍数です。」というメッセージのみが表示されることになる。

switch文

JavaScriptのもう1つの条件分岐のための仕組みは、switch文である。
switch文は式の評価結果がどのような値を取るかによって、複数の選択肢に分岐する制御分である。
同じ1つの式の評価結果によって複数の選択肢に分岐するような場合には、if文より簡単に記述できるため便利である。
逆に言うと、switch文で書くことができる条件分岐は、複雑にはなるがif文でも書くことができる。

次にswitch文を使った例を示す。
この例では、「朝」「昼」「夕」「夜」のいずれかをユーザに入力してもらい、入力によって挨拶の文言を変えている。
switch文の括弧の中にある式の値が、複数あるcase節の後の値のいずれかに合致すれば、その次の行のalert()関数から先が実行される。
実行している中でbreak文が現れると、そこでswitch文は終了する。
break文が無いと、そのまま次のcase節に続く部分まで実行されてしまうので注意してほしい。
例えば下の例では「夕」と入力すると、そのまま次の「case “夜”」の下にある部分が実行される。

また、どのcase節にも合致しなかった場合は、default節の次の行から実行される。

var word = prompt("朝/昼/夕/夜のいずれかを入力してください。");
switch (word) {
  case "朝":
    alert("おはようございます。");
    break;

  case "昼":
    alert("こんにちは。");
    break;

  case "夕":
  case "夜":
    alert("こんばんは。");
    break;

  default:
    alert("理解できません。");
}


練習問題3-

ボタンを押すと「今日の天気はなんですか?」というプロンプトが表示され、「晴れ」と入力すると「素敵な1日を!」、それ以外の入力をすると「今日も頑張りましょう!」とアラート表示されるプログラムを作成しなさい。

練習問題3-

「占う」というボタンを作り、ボタンを押して、乱数が0.1未満だったら「凶」、0.1以上0.33未満だったら「小吉」、0.33以上0.66未満だったら「中吉」、0.66以上だったら「大吉」とアラート表示されるプログラムを作成しなさい。

練習問題3-

2つのボタンを作って、1つは条件分岐をif-else文で、もう1つはswitch-case文で下記のプログラムを作成しなさい。

ボタンを押すと「今日の夕飯の気分を 洋食/和食/中華/その他 で答えてください」というプロンプトが表示され、
それぞれの入力に応じてお勧めのレストランをアラートで表示する。

練習問題3-

ボタンを押すと「曜日は?」というプロンプトが表示され、
そこに曜日を入力すると、次に「時限は?」というプロンプトが表示され、
時限を入力すると、自分が履修している科目がアラートで表示されるプログラムを作成しなさい。
ただし、何も履修していない曜日時限が入力された場合は、「何も履修していません」というアラートを表示しなさい。