記事では「何かと何かが等しい」などの比較をする記号を習得しました。==!=<<=>>=これらは比較する記号です。意識高い系の場合、「記号」は「子」と呼ぶんでしたよね。いうことは「比較する記号」は「比較子」ですよね。ここで疑問が出てきてしまいました。「比較する記号」のことを「比較子」ではなく「比較演算子」と呼んでいます。「比較を計算する記号」というわけですが、なぜ計算(演算)するのでしょうか。今回の記事では、なぜ「演算」という言葉が使われているかという疑問から出発して、比較演算子とwhile構文について理解を深めていきます。Arduinoの計算能力ちょっと驚くかもしれませんが、Ardunoボードを始め、多くのコンピュータは数字の比較ができないんです。{}と書いて、スイッチの状態である「digitalRead(SWITCH)」と「1」が等しいかどうか比較していましたよね。これ、どうみても比較です。一般的なコンピュータ、つまり計算機は、当然ながら計算は得意なのですが、できることはかなり限られています。Arduinoの場合、計算と言ってもできることはこれぐらいなんです。計算結果が0か0以外か判定する計算結果がプラスかマイナスか判定するこれだけといっても、実際には比較とか、掛け算、割り算、さらには少数の計算をしているのですが、一体どうしてるんでしょうか。実は、Arduinoボードの内部では、足し算、引き算、結果が0かマイナスかプラスかの判定だけで、スケッチに書かれた比較や掛け算割り算などの複雑な計算をやっているんです。そこで今回の記事では、Arduinoボードが比較をどのように実現しているのか一緒に詳しくみていきましょう。比較演算子の処理これから以下のスケッチのArduinoボード内部処理のようすを詳しくみていきます。1これはスイッチの状態を調べて、その値が1に等しいかどうか調べる、という動作内容のスケッチです。Arduinoボードはこのスケッチをどのように処理しているか、順番にみていきましょう。この比較をするには、最初にdigitalRead(SWITCH)を処理する必要があります。digitalRead(SWITCH)は以下のような値になるんでしたよね。0ここで、スイッチがOFFのケースを考えます。スイッチOFFの場合はdigitalRead(SWITCH)の値は1ですので、先ほどの比較のスケッチは「digitalRead(SWITCH)」の部分が「1」になるので、Arduinoボードは内部で以下のように変換します。1次に、Arduinoボードは「==」の左側の数字から右側の数字を引き算します。結果はどうなるかというと「0」ですよね。Arduinoボードは結果が0の場合はこの比較が成立している、0以外の場合は比較が成立していない、と判定します。このように、Arduino内部では比較を行う場合、引き算をしてその結果がどうなるかを判定しています。「==」などの比較の記号は「比較するための計算の記号」つまり「比較演算子」だったわけです。-□」という引き算を行い、結果がプラスであれば成立している、プラスでなければ成立していない、と判断します。他の比較の記号も全て、左側の数字から右側の数字を引いて、その結果がどうなるか判定しているわけです。これが「比較演算子」と呼ばれている背景です。比較の記号が「比較演算子」と呼ばれている理由はなんとなくわかりましたでしょうか。ここまでが、Arduinoボードが比較演算子のスケッチが成立しているか、成立していないか判定するまでの処理です。この先、さらにややこしくなります。先ほどの比較演算子のように、コンピュータ内部では、何かが成立しているか成立していないか、という判定が頻繁に行われます。3比較演算子の左側は3、右側も3ですので成立しています。8比較演算子の左側は5、右側は8ですので、成立していません。このように成立している状態、正しい状態を「真」(しん)と呼びます。英語では「true」(トゥルー)と呼んでいます。成立していない状態、正しくない状態を「偽」(ぎ)と呼びます。英語では「false」(フォルス)と呼んでいます。このように成立している状態、成立していない状態は、日本語を話す人であれば「真」か「偽」、英語を話す人であれば「true」「false」ですが、コンピュータ内部では数字で表しています。なんともわかりづらいですが、C/C++言語に限らず、他のプログラミング言語でも、真は0以外の数字、偽は0で表すことになっています。真の場合は0以外の数字ですが、一般的には数字の1が利用されています。数字の0Arduinoボードは比較演算子を処理するとき、計算をして計算結果を見て成立しているか成立していないか判定しました。Arduinoボードの内部ではその判定結果を真か偽かを意味する0か1かに置き換えています。それでは、Arduinoボードの中で、以下の比較がどのように行われているか、もう一度最初から順を追って見ていきましょう。1Arduinoボードは最初にdigitalRead(SWITCH)を処理します。この時、スイッチがOFF、つまりdigitalRead(SWITCH)の結果が1とします。Arduinoボードは上のスケッチを以下のように変えます。1これで比較ができるようになったので、Arduinoボードは「==」の左側の数字から右側の数字を引き算した結果を求めます。0」ですので、結果は0です。「==」の場合、結果が0であれば成立している、0以外であれば成立していないという判定になりますので、この比較は計算結果が0ということで成立している、と判定します。成立している、つまり真(true)ということがわかりましたので、Arduinoボードはこの比較を真を表す「1」に置き換えて処理が完了します。1成立している場合は、1に変換する、というわけです。なんだかわかったようなわからないような、という感じですので、実際にArduinoボードの動きをシリアルモニタで確認してみましょう。真か偽の判定それでは、新規スケッチを作成してください。スケッチ名は「true_false」にしておきましょう。このスケッチでは、比較演算子が最終的に「1」(真)か「0」(偽)のどちらかに変換される様子をシリアルモニタで確認します。確認用に以下のスケッチを作成しました。delay(1000);}この内容でスケッチを作成したら、ArduinoボードをPCに接続して、シリアルモニタウィンドウを開きます(ツール→シリアルモニタ)。準備ができたらスケッチをArduinoボードに送ります。3」の結果が表示されます。3」を演算して、その結果真であると判定したため「1」(真)と表示しています。それでは、比較が成立しないように書き換えて、その結果がどうなるか確認してみてください。5」は成立しませんので、この結果を表示するとどうなるか確認してみてください。成立しない場合は「0」(偽)が表示されますよね。C/C++言語に限らず、プログラミングの世界では「真」は0以外の数字(一般的には数字の1)、「偽」は数字の0で表現する、ということは非常に重要ですので、十分理解しておきましょう。3」にしても、左側から右側を引き算してその結果が0か0以外かでこの比較が成立するか判定していました。ここで、新しい言葉を覚えておきましょう。3」などの計算や比較を「式」と呼びます。数学でも式が出てきますので特に違和感はないですよね。Arduino内部では比較の式を、左側から右側を引き算してその結果が0か0以外かで成立するか判定しています。この判定する処理のことを「評価する」と呼びます。3』という式を評価すると結果は真(1)だ」などと言います。「評価」というと、何かランク付けするイメージが強いかもしれませんが、プログラミングの世界では「評価」をこのような意味合いで使用しています。この言い方はC/C++言語に限らず、全てのプログラミング言語で共通です。前回の記事で、while構文は以下のように書きます、と説明しました。while(条件)命令;実はこの説明はあまり正確ではないんです。while構文は以下がより正確な説明になります。while構文は、whileの括弧の中の式を評価した結果が「真」の間、「命令」を繰り返す、という動作をする構文なんです。おすすめできない書き方ですが、スイッチを押すとLEDの点滅を開始するスケッチは以下のようにも書けます。while構文では比較演算子ではなく、直接digitalRead(SWITCH)を書いています。digitalRead(SWITCH)は、スイッチがOFFの時は1、ONの時は0になります。1」と書いて、1と比較する必要はないわけです。このようなスケッチはわかりづらいので、書かないようにしてください。他の人が書いたスケッチやC/C++言語で書かれたプログラムでは、この仕組みを利用した書き方をする場合もあります。while構文の仕組みを十分理解しておくようにしてください。while構文をわかりやすく書くwhile構文の説明の最後に、スケッチをわかりやすく変更します。言われても、どこがどうわかりにくいか、って感じですよね。わかりにくい背景を説明します。わかりにくい部分はここです。1){}何がどうわかりにくいのか、ちょっと???ですよね。今まで一緒にスケッチを作ってきましたので、私たちはこのスケッチの意味がわかっています。他の人が急にこのスイッチを見た場合を考えてみてください。「digitalRead(SWITCH)」という部分は、読み取っている端子はおそらくスイッチだろう、ということが想像できます。「1」ってなんなんでしょうか。スイッチがONなのかOFFなのか、直感的にわかりづらいですよね。このように式の中に数字を直接書くとわかりづらいことが多々あります。そこで、スイッチONの時とスイッチOFFの時で、digitalRead(SWITCH)命令がどのような値になるのか、#defineで明確にしておきます。0このように定義しておくと、先ほどのwhile構文は以下のように書けます。SWITCH_OFF){}while構文は、式が真の間繰り返す、という処理をしますので、これを初めてみた人は「スイッチの値を読んで、その値がスイッチOFFの間、何もしないんだな」ということが想像できます。スケッチの中に数字を直接書く場合は、もう少しわかりやすく書ける方法があるか一度考えてみるようにしてください。電子工作のプログラミングでは、ずっと何かの処理を繰り返す、という動作をすることがいろいろな場面で出てきます。他の人が書いたスケッチでもずっと繰り返すという処理が出てきます。そのようなスケッチを読めるように、いくつか書き方を覚えておきましょう。繰り返す、ということは、whileの式が常に真であればOKです。真は「1」ですので以下のように書くと「処理」をずっと繰り返します。while(1){処理;}ただ、「1」と書くのは数字自体に意味があるのか単に真を表すために0以外の数字ということで「1」と書いてあるのかよくわかりませんよね。IDEではよく出てくる真と偽について、裏で以下のように定義してくれています。0「true」は「真」、「false」は「偽」の意味でしたよね。この#defineは見えないところで定義してくれているので、スケッチの中でいつでも使えます。そのため、他の人のスケッチを見ると、ずっと繰り返す場合は以下の書き方をよく見かけます。while(true){処理;}これでスタートスイッチの機能が実現できましたので、次回からいよいよ時間を数えるスケッチを作成します。