Section 1.9 条件分岐でよく使う演算子

今回は条件分岐でよく使う演算子を紹介するね。
前回== っていう演算子を使ったよね。
== 演算子は、左側と右側が等しかったら真、等しくなかったら偽になるんだ。
ってことは…左側と右側の値が等しかったら if のすぐ後に書いてあるスクリプトが実行されて、 等しくなかったら else の後に書いてあるスクリプトが実行されるってことだよね。
うん、そういうこと。
こういう演算子のことを同定演算子って言って、全部で4種類あるんだ。

<同定演算子>
==左側と右側が等しければ真、等しくなければ偽。両側の値の型が違う場合は自動的に変換されてから比較されます。
!=左側と右側が等しければ偽、等しくなければ真。両側の値の型が違う場合は自動的に変換されてから比較されます。
===左側と右側が等しく、かつデータ型が一致していれば真、そうでなければ偽。
!==左側と右側が等しく、かつデータ型が一致していれば偽、そうでなければ真。

==!= は結果が逆になるんだね。
うん。
===!== も逆になるよ。
===== ってどこが違うの?
==』の方は、両側のデータ型が違ってる場合には、 自動的に同じ型になるように変換して比較するの。
だから、両側の型が一致してなくても、型を変換すれば等しくなる場合には真になるんだけど、 『===』は両側のデータ型が同じじゃないと偽になるんだ。
例えばこんな感じ。

== 演算子と === 演算子の違い>

var a = 1;    // a は整数型の 1
var b = "1";  // b は文字列型の "1"

if(a == b)
    System.inform("条件式は真です。");
else
    System.inform("条件式は偽です。");

if(a === b)
    System.inform("条件式は真です。");
else
    System.inform("条件式は偽です。");

実行してみて。
うん。
……最初は『条件式は真です。』って表示されたけど、次は『条件式は偽です。』って表示されたね。
変数 b は文字列だけど、§1.6 で出てきた単項 + 演算子とかで数値に変換すると、 変数 a と同じ 1 になるよね。
うん、そうだね。
== 演算子は、両側の型が違ってたら、型を合わせてから比較するんだ。
だから、この場合は真になるってワケ。
でも、=== 演算子の方は型が違うと偽になるから、片方が整数型でもう片方が文字列型だと、 変数の値に関係なく偽になるの。
だから最初は真で次は偽になるんだね。
そういうこと。
じゃあ次は比較演算子。これも4種類あるよ。

<比較演算子>
<左側が右側より小さければ真、そうでなければ偽。
>左側が右側より大きければ真、そうでなければ偽。
<=左側が右側以下ならば真、そうでなければ偽。
>=左側が右側以上ならば真、そうでなければ偽。

これはわかりやすいね。
だね。
ちなみに、比較演算子は片方が数値でもう片方が文字列だった場合には、文字列を数値に変換してから比較するんだ。
あ、そうなんだ。
あと、両方とも文字列だった場合には、文字コード順っていう順序に従って比較するんだけど、 ちょっとややこしい話になるから、ここでは詳しい説明はパスするね。
う、うん…
じゃ、次は || 演算子と && 演算子。
これはそれぞれ論理 OR 演算子論理 AND 演算子って言うんだ。

<論理 AND 演算子・論理 OR 演算子>
||左側か右側のどちらか、または両方が真であれば真、そうでなければ偽。
&&左側と右側の両方が真であれば真、そうでなければ偽。

これは2つ以上の条件を同時に判定するときに使うんだ。
こんなふうに。

<論理 AND と論理 OR 演算子の使用例>

var a = 1;
var b = 2;

if(a > 1 || b > 1)
    System.inform("a と b のうち少なくとも一方は 1 より大きいです。");
else
    System.inform("a と b はどちらも 1 以下です。");

if(a > 1 && b > 1)
    System.inform("a と b はどちらも 1 より大きいです。");
else
    System.inform("a と b のうち少なくとも一方は 1 以下です。");

えっと、変数 a1 で、変数 b2 だから、 『a > 1』は偽で、『b > 1』は真になるよね。
うん。
ってことは、『a > 1 || b > 1』の方は『真 || 偽』だから真になって、 『a > 1 && b > 1』の方は『真 && 偽』だから偽になるんだよね。
ん、そういうこと。
それじゃ最後は ! 演算子。
これは論理否定演算子って言って、右側にあるものの真と偽を逆にするんだ。

<論理否定演算子>
!右側にあるものの真偽を逆にします。

じゃあ ! って単項演算子なの?
うん、そうだよ。
使い方はこんな感じ。

<論理否定演算子の使用例>

var a = 1;

if(!(a == 1))
    System.inform("a は 1 ではありません。");
else
    System.inform("a は 1 です。");

えっと…『a == 1』は真で、 それに ! がついてるから、 偽になって、「a は 1 です。」って表示されるのかな?
うん、そうそう。
あ、一つ質問してもいい?
なに?
なんで条件式にカッコがついてるの?
!a == b』でいいんじゃないの?
ああ、それは ! 演算子の方が == 演算子より優先順位が高いからだよ。
優先順位?
1+2×3 っていくつになる?
えっ?
えっと、先に掛け算して 1+6 になるから、7 だよ。
その『掛け算が足し算より先』っていうのが優先順位。
あっ、そういうことなんだ。
そ、そういうこと。
! 演算子の演算は == 演算子の演算より先って決まってるから、 『!a == b』って書くと『(!a) == b』だと 見なされて、!ab が比較されちゃうんだ。
なるほどね〜。ab の比較を先にやるために、カッコをつけてるんだね。
あ、でも演算子の優先順位ってどうやったらわかるの?
足し算とか引き算とかの演算子は算数と同じ規則だからわかりやすいと思うよ。
それ以外は TJS2 リファレンスの『式と演算子』っていう項目に、優先順位の低いものから順に書かれてるから、 それを見れば判るよ。
……なんか演算子の種類が多すぎてよくわからないんだけど…
うん。だから、よく使う演算子だけ優先順位を覚えて、それ以外はその都度調べるようにするか、 とりあえずカッコをつけとく、って方法もあるかな。
とりあえずカッコをつけとく…って?
例えば、普通は『a = 1 + 2 * 3』って書くけど、 『a = 1 + (2 * 3)』って書いても同じ結果になるから、 優先順位がよく判らない時は、先に計算したい所にカッコをつけとけば確実でしょ。
あ、確かにそうだよね。
それに、長い式だと適度にカッコが入ってる方が読みやすいしね。
例えば『a == b && c >= d - 2 && e < f』って書くより 『(a == b) && (c >= d - 2) && (e < f)』って書いた方が読みやすいでしょ?
うん、カッコがある方がわかりやすいね。
ま、だからといってカッコを入れすぎると却って読みにくくなるから、 優先順位の関係でカッコが必要な場合はしょうがないとして、別に必要じゃない時は、 読みやすさを考えてカッコを使うようにした方がいいんじゃないかな。
うん、わかった。
じゃ、これで条件分岐でよく使う演算子も一通り紹介したことだし、 OK とキャンセルで処理を分けるスクリプトを書いていこっか。
は〜い。
まず、§1.7 で作ったスクリプトがこれ。

§1.7 で作ったスクリプト>

var value = +System.inputString("何分後?""数字を入力してください。""");
var d = new Date();
var hour = d.getHours();
var minute = d.getMinutes() + value;
hour += minute \ 60;
minute %= 60;  
hour %= 24;  
System.inform("今から " + value + " 分後は " + hour + " 時 " + minute + " 分です。");

inputString メソッドで入力された文字列を数値として受け取って、 それが例えば 100 だったら、今から 100 分後の時間を表示するんだよね。
ん、そう。でもキャンセルボタンが押されたら時間を表示する必要はないから、 キャンセルボタンが押された場合は「キャンセルされました。」って表示して終わりにするよ。
うん、わかった。
でも、キャンセルボタンが押されたかどうかって、どうやったらわかるの?
キャンセルボタンが押された場合は、inputString メソッドの実行結果が void になるから、それで判るよ。
void って確か…「何も表してない」っていう意味、だったよね?
うん。void については §1.4 で説明したよね。
キャンセルボタンが押されたってことは、何も入力されてないってことだから void になるんだ。
じゃあ、valuevoid と等しいかどうかってのを条件にすればいいんだよね?
ううん、それじゃダメ。
え、どうして?
valueinputString に 単項 + 演算子をつけたものを代入してるでしょ。
うん。
void に単項 + 演算子をつけると 数値型に変換されて void じゃなくなっちゃうんだ。
え、そうなの?
うん。だから、一旦 valueinputString の実行結果をそのまま代入して、 void じゃなかったら単項 + 演算子をつけて数値にすればOK。
なるほどね。
じゃスクリプトを書き換えてみて。
うん、わかった。

<OK ボタンが押された時とキャンセルボタンが押された時で違う処理をするスクリプト>

var value = System.inputString("何分後?""数字を入力してください。""");

if(value == void)
{
    // value が void → キャンセルボタンが押された時の処理をします
    System.inform("キャンセルされました。");
}
else
{
    // value が void でない → OK ボタンが押された時の処理をします
    value = +value;
    var d = new Date();
    var hour = d.getHours();
    var minute = d.getMinutes() + value;
    hour += minute \ 60;
    minute %= 60;  
    hour %= 24;  
    System.inform("今から " + value + " 分後は " + hour + " 時 " + minute + " 分です。");
}

これでいいかな?
じゃ、とりあえず実行してみよっか。
今回はキャンセルボタン押してみるね。
うん。
……うん、ちゃんと「キャンセルされました。」って表示されたよ!
今回の場合はこれでもいいんだけど、1つ直した方がいい所があるね。
えっ、どこ?
if の条件式のところで、== 演算子を使って比較してるよね。
う、うん。そうだけど…
void と等しいかどうかを判定するときには、=== 演算子を使うんだ。
=== 演算子って、型が同じかどうかもチェックする演算子だよね?
どうしてこっちじゃなきゃいけないの?
じゃあ、このスクリプトを実行してみて。
うん。

void との比較>

var a = 0;    // a は整数型の 0 なので void ではありません
var b = "";   // b は空文字列なので void ではありません

if(a == void)
    System.inform("a は void です。");
else
    System.inform("a は void ではありません。");

if(b == void)
    System.inform("b は void です。");
else
    System.inform("b は void ではありません。");

あれ!? どっちも「void です。」って表示されちゃったよ!?
なんで??
== 演算子は比較するときに両側の型が違ってたら、自動的に同じ型になるように変換してから比較するって言ったよね。
うん。
実は、void は整数型に変換すると 0、 文字列型に変換すると 空文字列 になるんだ。
だから、== 演算子で比較すると型が変換されて等しくなっちゃうってワケ。
そうなんだ…
だから、void かどうかを判定する時には、型が合ってるかもチェックしないといけないんだ。
上のスクリプトで『a === void』って書くと、 avoid でない限り真にはならなくなるからね。
そっかぁ…じゃあ、これでいいのかな?

<OK ボタンが押された時とキャンセルボタンが押された時で違う処理をするスクリプト(修正版)>

var value = System.inputString("何分後?""数字を入力してください。""");

if(value === void)
{
    // value が void → キャンセルボタンが押された時の処理をします
    System.inform("キャンセルされました。");
}
else
{
    // value が void でない → OK ボタンが押された時の処理をします
    value = +value;
    var d = new Date();
    var hour = d.getHours();
    var minute = d.getMinutes() + value;
    hour += minute \ 60;
    minute %= 60;  
    hour %= 24;  
    System.inform("今から " + value + " 分後は " + hour + " 時 " + minute + " 分です。");
}

ん、これでOK。
void と比較するときには === 演算子を使うって覚えといてね。
は〜い!
じゃ、これでとりあえずの目標も達成できたから、今回はここまで。
また次回ね!


前へ | TOP | 次へ