電子工作入門プログラミング入門-基礎1今回は変数の扱いについて補足します。今までの記事で、変数の性質について詳しく説明していませんでしたので、この記事では変数についてもう少し掘り下げます。C/C++言語では以下の変数型が用意されていましたよね。上の型の名前とは別に、変数のサイズ(メモ帳の大きさ)を数字で表現した変数型の書き方もありましたよね。char」などの変数型を使う人もいますので、両方の変数型を頭に入れておきましょう。ところで、変数型によって扱える数字の範囲が異なりますが、そもそも数字の範囲を超えたらどうなるのでしょうか。IDEのことだから、また例のごとく大怒りしそうですよね。それが、変数型の数字の範囲を超えたら、それはもう大怒りするに違いありません。この記事では、いくつかスケッチを作成して、変数の性質を調べていこうと思います。変数型の範囲を超えたらどうなるか変数の範囲を超えたらどうなるのか、以下の2つの観点で性質を調べてみたいと思います。数値範囲をオーバーした場合どうなるか?例えば「uint8_t」型の変数は0〜255の範囲の数字しか扱うことができません。200」などのように結果が255を超えるような計算をするとどうなるのでしょうか。200」などのように結果がマイナスになるような計算をするとどうなるのでしょうか。Microで試してみましょう。数値範囲をオーバーした場合どうなるか?まずはuint8_t型(0〜255)の変数に「300」を代入して、その変数をシリアルモニタに表示するスケッチを作成します。以下のように作成してみました。300;」というように扱える範囲を超える数字を代入してみました。その値をシリアルモニタに表示してみます。IDEですので、まぁ、これも怒られるのでしょう。チェックボタンでスケッチに問題ないか確認してみましょう。uint8_t型の変数に300を代入したら怒られるかと思ったら、「コンパイルが完了しました」と表示されて特に何も問題なくスケッチのチェックが終わりました。これはかなりまずい状況です。いうのは学生の皆さんはまだ経験がないかもしれませんが、いつもちょっとしたことで怒っている人が、明らかに怒る状況なのに怒らない、というのは怒りを通り越して別の次元にいってしまった、ということなんです。この状況になると謝ってもどうにもならない状況、というのが経験上言えることです。Microの中では何が起こっているのでしょうか。上のスケッチはシリアルモニタに数字を表示するようにしていますので、シリアルモニタで変数「test」の値を確認してみましょう。300を代入すると結果は44でした。これはどういうことなのでしょうか。このことを理解するために、別のスケッチを作成して動作を確認してみます。loop関数では何もしない}このスケッチはuint8_t型の変数testを使って、1を足しながら結果をシリアルモニタに表示する、という内容です。シリアルモニタには以下のよう0、1、2...と表示されるはずです。01234567...変数testの範囲は0〜255ですので、255まで足し算したら次はどうなるかその部分を確認すると、255に1を足すと0になっています。変数はその範囲を超えると最初に戻って0にしてしまうんです。先程のスケッチでは、uint8_t型のtestに300を代入しましたが、これは、255を超えています。255より大きい数はどうなるかというと、256は変数testにとっては0、257は1、ということでこれを続けていくと300は44になります。最初のスケッチの結果が44というのはこのような仕組みだったんです。300;」と直接300を代入しましたが、以下のように255を超える計算をしても、超えた分は0からカウントされます。以下の計算結果も44になります。IDEは怒りませんでした。実はこれは本当に怖いことなんです。プログラミングをしているといろいろな不具合に遭遇(そうぐう)します。不具合にはいろいろな原因がありますが、そのうちのひとつがこの変数の範囲を超えてしまうケースです。この記事の最後にミニチャレンジ課題があります。課題のスケッチはうまく動かない状態になっています。扱える数字の範囲を頭に入れて課題を解いてみてください。いうことで、変数の数値範囲をオーバーした場合このようなことがおきますので、プログラミングする場合は数字の範囲に十分注意するようにしましょう。プラスの範囲の変数にマイナスを代入したらどうなるか?次に、uint8_t型の変数にマイナスの数字を代入してみましょう。次のようなスケッチを作成してみました。loop関数では何もしない}このスケッチはuint8_t型、つまり0〜255の数字を代入できる変数testに「-1」を代入してその値をシリアルモニタで確認する、という内容です。先程の数値範囲オーバーの時と同じく、スケッチをチェックしても何も指摘されません。Microボードに送ってシリアルモニタで結果を確認すると、またまた不思議な結果になりました。-1を代入したのに結果は「255」です。このような結果になるのか、その背景を確認しておきましょう。uint8_t型、int8_t型は両方とも256個の数字を扱うことができます。uint8_t型とint8_t型の変数が扱う数字を以下のような256個のマスがあるの表で考えてみます。uint8_t型の変数は、この256個の数字のマスに0〜255の数字を割り当てています。+127の数字を以下のように割り当てています。並び方が変な気がしますよね。この理由を説明するには「2進数」というコンピュータ内部の理解が必要ですので、すみません、ここではこのようになっている、と理解しておいてください。uint8_t型とint8_t型の数字の割り当てを並べると、以下のようになります。0〜127の数字に関しては、uint8_t型もint8_t型も意味は同じですが、uint8_t型の128〜255は、int8_t型ではマイナスの数字の意味になってしまうんです。uint8_t型の変数に「-1」を代入しても、uint8_t型にとっては「255」という意味なので、先程のスケッチではシリアルモニタに「255」と表示されてしまったわけです。マイナスの数字の扱いについてはちょっとややこしいですね。使用する変数型Arduinoの公式サイトにはArduinoの命令、関数のマニュアルがあります。そのマニュアルにはサンプルスケッチが掲載されていますが、多くのスケッチでは「int型」の変数が使用されています。公式サイトの変数型はint型なので、int型を使うことが推奨されているのかな、と思ってしまいますよね。そこでスケッチで使用する変数型について補足します。結論としては普通に変数を宣言する場合はint型で問題なしただし、必要な時に適切な変数型を使用できるように、変数型は常に意識することという感じです。それでは詳しく説明します。このシリーズで使用している「int8_t」や「uint8_t」などは、扱える数字の範囲やプラス、マイナスの扱いに充分注意する必要があります。マイナスの数字を扱う変数なのに「uint8_t」型で変数を宣言してしまうと、スケッチがうまく動きません。32767」の数字を扱えるのでまず問題が起きることありません。いうことは、「int8_t」型や「uint8_t」型など、間違えると問題が起きる変数型を使うよりも、全部「int」型にしてしまった方が楽だし安全ですよね。いっても、常に「int」型使うと問題が発生することがあります。「int」型はメモリを2バイト使用します。一方で「int8_t」型は1バイト使用します。2000バイト必要というように、int型はint8_t型の2倍のメモリを使用してしまいます。記録する数字が温度データなどのように「-128〜127」で治るような場合、int8_t型で十分です。32767」の範囲を扱えますが、ちょっともったいないですよね。Microのメモリは約2500バイトしかありません。このように多くのデータを扱う場合は、変数型を意識しないとArduinoの能力を十分に活用することができなくなってしまいます。以上のことから、Arduinoの公式サイトに掲載されている参考スケッチは「int」型の変数を使用してより安全なスケッチにしています。このシリーズでは、間違えると問題が起きやすい変数型を使用していますが、変数型の理解を深めるために「uint8_t」や「int8_t」などを使用しています。変数の範囲について、実際のケースを確認してみましょう。以下のスケッチは1秒に1回LEDを光らせて、5分経過したらブザーを鳴らすスケッチです。残念ながらこのスケッチはLEDの点滅を永遠に繰り返してブザーが鳴ることはありません。このスケッチが正しく動作するように修正してみてください。