Logical Thinking and Programming in 2012 Autumn
Minohara Class


第4回 条件分岐

条件分岐

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

比較演算

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

プログラミング言語には、ある式が成立する(真、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といった複数のコードが存在しています)という番号によって表現されています。文字は、この文字コードの順番によって大小決まります。このため、あいうえお順のようには成らない事に気をつけてください。

☆練習問題4-1

  1. nが整数だとした場合に次の条件を表す条件式を記述しなさい。

基本的なif文

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

基本的なif文の動作

基本的なif文の動作

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

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

たとえば、入力された値の絶対値を求めるスクリプトは以下のように記述します。

var value = prompt( "値を入力してください", -39 );
if ( value < 0 ) {
	value = -value;
}
document.write( "絶対値は、" + value + "です。" );

else節を伴うif文

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

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

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

<strong>else</strong>節付きのif文の動作

else節付きのif文の動作

たとえば、入力された値が奇数か偶数かを判定するスクリプトは以下のように記述します。

var number = prompt( "値を入力してください", 14 );
if ( number % 2 == 0 ) {
	document.write(  number + "は偶数です。" );
} else {
	document.write(  number + "は奇数です。" );
}

else if節を伴うif文

if文を使って更に条件を細かく指定することもできます。「○○の時は○○○、そうでなく△△の時は△△△、そうでもなく□□の時は□□□、そうでもなく××の時は×××を実行する」といった具合です。このような条件分岐を記述するためには下記のようにします。このとき、上から順番に条件を確認していき、始めに当てはまったもののみが実行されることに気をつけてください。もし、ある条件1(例: num < 10)が別の条件2(例: num < 100)にすっぽり当てはまる場合、条件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 {
  どの条件にも当てはまらない場合のみ実行される処理ブロック
}

では、else if節を伴うif文を使った実際のプログラムの例を見てみましょう。下記のプログラムを見てください。 ユーザに値を入力してもらいます。 入力された値numを2で割り余りが0かどうかを調べています。 つまり、numが2の倍数かどうかを調べている訳です。 もし、2の倍数の場合はその直後のブロックの中を実行します。つまり、2の倍数であることを表示しています。 もし2の倍数でなかった場合は、次のelse ifへ飛びます。ここでは、numが3の倍数かどうかを調べています。 3の倍数の場合には、2の倍数の時と同様にその直後のブロックを実行し、3の倍数であることを表示しています。 2の倍数でも3の倍数でもない場合は、最後のelse節に飛び、どちらの倍数でもないことを表示しています。

  var num = prompt( "値を入力して下さい", 12 );

  if (num % 2 == 0) {  // 2の倍数
     document.write( num+"は2の倍数です" );
  } else if (num % 3 == 0) {  // 3の倍数
     document.write( num+"は3の倍数です" );
  } else {  // 上記以外なら
     document.write( num+"は2の倍数でも3の倍数でもありません" );
  }

以下の例は、2の倍数か3の倍数かによって、フォームの背景色を変えています。 値を入力して、どのような色になるか実行してみて下さい。



数値を入力してください:

上記の例において、「6」や「12」など、2の倍数でも3の倍数でもある数値を入力するとどうなるでしょうか? 青と赤を混ぜて紫になるでしょうか? そうはなりません。プログラムは基本的に上から下にむけて実行されます。「6」や「12」が入力された場合には、まず最初のif文で評価されます。「6」や「12」は2の倍数ですので、このif文の条件式が成立し、フォームの背景が青になります。一度条件に合致してしまったので、それ以降のelse ifやelseは飛ばされます。よって、「6」や「12」など、2の倍数でも3の倍数でもある数値が入力された場合には背景が青くなります。

たとえば、入力された値によって成績を判定するスクリプトは以下のように記述します。

var score = prompt( "点数を入力してください", 78 );
if ( score >= 80 ) {
	document.write(  score + "点の判定はAです" );
} else if ( score >= 60 ) {
	document.write(  score + "点の判定はBです" );
} else if ( score >= 40 ) {
	document.write(  score + "点の判定はCです" );
} else {
	document.write(  score + "点の判定はDです" );
}

☆練習問題4-2

  1. MonthClassify:入力された月が、小の月(30日以下の月)か大の月(31日ある月)かを求めるスクリプトを書きなさい。2,4,6,9,11月が小の月です。
  2. EnglishNumber:入力された2桁までの10進数に対して、それを英語でどう読むかを表示するスクリプトを書きなさい。「25」→「twenty five」、「12」→「twelve」、「7」→「seven」
  3. NengoConverter:入力された西暦の年に対して、年号とその年号における年をつけて表示しなさい。たとえば、2012と入力された場合は、「2012年は平成24年です。」と表示します。慶應より前の年号には「慶應以前です。」と表示します。ちなみに、日本では年号は「大化」(西暦645年)から始まります。慶應以降の最初の年(元年)の西暦は、「慶應→1865年、明治→1868年、大正→1912年、昭和→1926年、平成→1989年」となっています。

論理演算子

より複雑な条件を記述するためには、幾つかの条件を組み合わせる必要があります。例えば、ある数字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より小さくない

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

下記のスクリプトは、入力された値が、3の倍数でかつ7の倍数であるかどうか判定しています。

var  number = prompt( "値を入力してください", 21 );
if ( number % 3 == 0 && number % 7 == 0 ) {
	document.write( "入力された値:" + number + "は、3と7の公倍数です。" );
}

論理演算にはいろいろな特徴があります。例えば、否定の否定は肯定です。論理演算を使うと「比較演算」は「!!(比較演算)」と同じになります。また、論理演算には「ド・モルガンの法則」と呼ばれる有名な法則もあります。その法則では、次の左右の論理式が等しいことが証明されています。

!( 条件1 && 条件2 )!(条件1)|| !( 条件2 )
!( 条件1 || 条件2 )!(条件1) && !( 条件2 )

また比較演算も論理演算を使って書き換えることができます。例えば、「a<=b」は「a<b || a == b」と分解して記述することができます。あるいは、「以下」というのは「より大きくはない」ということでもあります。それに従えば、「a<=b」は「!(a>b)」と同じです。 逆に、「!(a<=b)」は、「a>b」になります。

下記のスクリプトは、入力された値が、指定された範囲外にある場合にエラーを表示します。

var  number = prompt( "値を入力してください", 21 );
if ( !(100 <= number  && number <= 200) ) {
	alert( "入力された値:" + number + "は、100と200の間にありません。" );
}

条件の部分をド・モルガンの法則などを使って書き換えることができます。

!(100 <= number && number <= 200) 
!(100 <= number || !(number <=200)
number < 100 || number > 200

☆練習問題4-3

  1. InRange: 入力された値が、1から12までの範囲に入っているかどうか確かめて、その値を表示します。
     もし、1よりも小さい値が入力されたら、1にして表示します。
     もし、12よりも大きい値が入力されたら、12にして表示します。
     範囲内でも、入力された値が実数であったら、整数に直して表示します。
  2. ThreeDigits:入力された値が3桁の数字かどうかを判定するスクリプトを書きなさい。 3桁で最小値は100ですね。最大値は999です。
  3. LeapYear:入力された年が閏年かどうか求めるスクリプトを書きなさい。 閏年の条件は次の通りです。
    西暦年が4で割り切れる年は閏年
    ただし、西暦年が100で割り切れる年は平年
    ただし、西暦年が400で割り切れる年は閏年

if文で間違いやすい例

if文を使うとスクリプトの書き間違いが発生します。中には、文法エラーが発生しないものもあります。

if ( number % 2 == 0 ) {
	document.write( "入力された値は偶数です。" );
} else ( number % 2 == 1 ) {
	document.write( "入力された値は奇数です。" );
}

上記のようにelseに反対の条件を記述する律義な人がいます。この場合は、文法エラーになります。 elseは、「それ以外の」という意味なので、ifを伴わない限り条件を記述する必要はありません。

if ( number >= 100 ) {
	document.write( "入力された値は100以上です。" );
} if ( number >= 50 ) {
	document.write( "入力された値は50以上です。" );
}

else if のelseを書きわすれてしまうと、2つのif文になってしまいます。上記の例では、 numberの値が100以上の場合は、「100以上です」と「50以上です」の両方の文が表示されます。 この場合は、文法的なエラーにはなりません。

if ( number % 2 == 0 ) {
	document.write( "入力された値は偶数です。" );
} else ;  {
	document.write( "入力された値は奇数です。" );
}

elseの後に間違ってセミコロン「;」を入れてしまうと、そこで文の終了になってしまうので、 次のブロックは、単なるブロックとして処理されてしまいます。上記の例では、必ず「入力された値は奇数です。」の 表示がされてしまいます。この場合も、文法的なエラーにはなりません。

if ( number % 2 == 0 ) ; {
	document.write( "入力された値は偶数です。" );
} 

if 文の条件指定の後にセミコロン「;」をいれても、次のブロックと切り離されてしまいます。 もし、else節がある場合には、そこで文法エラーになりますが、else節がない場合は文法エラーに なりません。上記の例では、奇数の場合でも必ず「入力された値は偶数です。」が表示されてしまいます。

条件式で間違いやすいのは、以下のような記述です。これは、JavaScriptではエラーになりません。

if ( -10 <= x <= 10 )  {
	document.write( "入力された値は-10から10までの範囲にあります" );
} 

この条件式は、「-10 <= x && x <=10」と記述しなければなりません。 たとえば、xの値が20であったとしましょう。そうすると、次のような評価になります。 演算子は、代入演算子を除き左結合性(左から順番に評価される)を持っています。

-10 <= 20 <= 10 
true  <= 10
1 <= 10
True

まず「-10<=20」の部分が評価され、これは条件式を満足しているので、trueと評価されます。 trueと数値を比較すると、trueが数値に置き換わります。このときに、多くの場合は-1あるいは1と いった値に置き換わります。そのために、次の評価は「1 <= 10」という形で評価され、これも 満足しているので、trueになります。このように実際には、範囲外のものでも条件にあっていると されてしまいます。注意して下さい。