「コンピュータと電気」小・中学校でプログラミングを教える先生のためのコンピュータサイエンス入門

# はじめに
この記事は、Qiita常連の技術者の皆さま方というより、主に小・中学校で2020年度からなんらかの形で「プログラミング教育」に関わる方を対象と想定して書きました。それから、この記事を元にYouTube動画も投稿しました。

[![【プログラミング未経験者向けコンピュータサイエンス １】コンピュータが電気の力で動いているって、どういうことなの？](http://img.youtube.com/vi/hdxdpLIlGJc/0.jpg)](https://www.youtube.com/watch?v=hdxdpLIlGJc)

とにかく未経験の人に、出来るだけ伝わるようにやってみました。（動画ではド素人の奥さんを捕まえて教えてますｗ）

-----


# コンピューターは「分かりにくく作ってある」
これまで子供たちに「2進法」や「プログラミング（micro:bit、JavaScriptなど）」を教える機会がありました。その時、参加した子供たちの保護者から、下のような質問やフィードバックを頂くことがありました。

- コンピューターが電気の力で動くとありますが、具体的にどういう仕組みで動くんですか？ 
- 2進数やIF文を教えてもらいましたが、それとコンピュータの関係がよく分からないようです
- 2進数が「なぜ」プログラミングに必要なのか分からないと言っていました

といったように、スッキリと理解できないもどかしさを感じていることが分かりました。教える側にとっても、このトピックはプログラミング教室でよく教えるIF文や変数などの内容よりも、教えるのが難しいトピックだと感じます。

なぜかというかと：

- コンピューターの核心部品であるCPUがそもそも非常に複雑
- コンピューターは電気の力で動いているということを意識せずに扱えるように作ってある
- プロフェッショナルですらプログラミングで2進数を使うことはほとんどない（もちろん使う場合もありますが出来るだけ10進数を使えるように工夫されます）
- コンピューターは幾層もの抽象化レイヤーで構成されていて、自分が関わっている抽象化レイヤーより下層のレイヤーを気にしなくてもいいように工夫してある（上層のレイヤーも気にしなくていいという場合も多い）

つまり、ひとことで言うと「わざと分かりにくくしてある（分からななくても済むようにしてある）」から理解するのも教えるのも大変なんだと思うのです。

では、そういった分かりにくさを踏まえた上で、どのようなアプローチで教える（学ぶ）のが効果的かを考えてみました。具体的には以下の3つの点をしっかりと伝えることが重要だと思うのです。

1. コンピューターはデジタル情報を取り扱う機械だということ
2. デジタル情報をどのようにして電気で表しているのかを理解する
3. 「１」と「０」があれば2進法を使って数値を表せることを理解する
4. ほとんどの情報は数値に置き換えて表せることが出来る
5. コンピュータに指示を出す命令語も数値化されたデジタル情報である

# コンピューターはデジタル情報を取り扱う

コンピューターが普及する前の社会を思い出してみましょう

- 文字情報は紙に筆記具で書いていた
- 音声情報はレコードや磁気テープに信号の強弱として記録していた
- 画像情報はフィルムに化学反応の強弱として記録していた
- 情報は電波の強さなどを使って伝達していた（AMやFMラジオなど）

これらはアナログ情報です。残念なことに今の子供たちにはピンとこないので、別の例えが必要でしょう。

- 照明の明るさ
- スピーカーから流れてくる音の大きさ
- 50メートルを何秒で走れるか

などはどうでしょう。それぞれ関して、「明るい・暗い」や「音が大きい・音が小さい」、「足が速い・足が遅い」という分類の間に、より細かい無数の「程度」がある、と説明するわけです。「やや明るい」とか「ちょっと薄暗い」とかそういう曖昧な部分。そのように、アナログ情報は「連続性」のある情報だという認識をまず固めるわけです。

アナログ情報の弱点のもうひとつは「劣化」です。記録された情報が年月を経て、意図せず変化してしまうこともあるし、人から人に伝えるうちに、最終的に最初とは違う程度になることがある。例えば、ある人の声の大きさを、実際に声を使って人から人に伝えていくと、結果は全く違う声の大きさになってしまうかもしれません。外界からの影響でノイズが入ってしまうのもアナログ情報の特徴です。

対して、デジタル情報は、情報を数値化・数量化して、具体的な「数値」として記録します。数値の解釈はひとつしかないので、同じ数値であり続けるし、伝える際も劣化することはありません。

近年、様々なアナログ情報は、デジタル情報に置き換えられてしまいました

- 文字情報は文字コードという数値で記録されるようになった
- 音声情報は1秒間に何万回という頻度でサンプルされ、その数値を記録して保存するようになった
- 加増情報は座標の各点にある色を数値として表して保存するようになった
- 情報は電波で数値を送信することで伝達するようになった

そして、コンピューターこそが「アナログ→デジタル」という情報の表し方の革命の最大の立役者なのです。

このように、コンピューターを理解するには、コンピューターが取り扱う「デジタル情報」というものが何なのか、アナログ情報とはどう違うのか理解することが大切だと理解してもらえると思います。

# デジタル情報をどのようにして電気で表しているのか

電気はそもそもアナログ的な性質を持っています。電圧や電流などには「強さの程度」があり、電圧が高い、やや高い、などといった程度のニュアンスを含む表現が出来ます。普段の生活で使う電池にもいろんな種類があって、電圧も異なります。1.5ボルトのものもあれば9ボルトもあるし、いくつかを合わせて3ボルトや4.5ボルトにすることも出来ます。さらに、私たちがよく使う乾電池なども、仮に1.5ボルトと表記してあったとしても個体によっては1.5ボルトより若干低かったりします。さらに、外界の影響を受けて電圧が一瞬だけ低くなったりすることもあります（例：落雷や停電の時を思い出しましょう）。このように、電圧の強さをピタっと安定した強度で保つのは実は結構難しいのです。

そこで、電圧をおおざっぱに「電圧が高い」と「電圧が高いとも低いとも言えない」と「電圧が低い」という3つに分けて、真ん中の「電圧が高いとも低いとも言えない」状態は解釈を保留することにしたのです。こうすることで、例えば5ボルト～０ボルトの電圧を使うなら2ボルトから4ボルトの範囲を挟んで「高い・低い」にはっきりと分けることができます。「高い」状態の電圧は4.98ボルトであったり4.893ボルトであるかもしれませんが4ボルトという閾値より高ければ「高い」として扱われるので、多少の電圧の誤差は無視できるようにしたのです。こうして電圧の「高い・低い」を使って、2つの状態を表すことが出来るようになりました。この時「電圧が高い＝１」と「電圧が低い＝０」というように考えると、デジタル情報の最小単位であるbitという考え方が誕生するのです。

さてそもそも「情報」とは、アナログだろうがデジタルだろうが「状態を変化させること」が出来て初めて便利なものになります。例えば、ある会社の株価情報が、ある瞬間の価だけを表し続けるのであれば役にたちません。情報は変化するので、デジタル情報も変化します。「ある」から「ない」になったり、数値が40から41になったりします。デジタル情報の最小単位であるbitを電圧で表す時も、１から０になったり、０から１になったりします。幸い、「電圧が高い」と「電圧が高いとも低いとも言えない」と「電圧が低い」という3つのグループに分けることで、5ボルトが0ボルトに変化するとき、ほんの一瞬だけ「電圧が高いとも低いとも言えない」状態を通り過ぎていきますが、曖昧な瞬間は無視されて、きちっと１から０に変化してくれます。０から１になる時も同じです。

このようにして、本来はアナログ的な性質を持つ電気の力を使って、デジタル情報を数値として取り扱う基礎となるbitを表すことが出来るようになったのです。

# 「１」と「０」があれば2進法を使っていろんな数値を表せる

ここで「コンピューターはデジタル情報を取り扱う」という話と「デジタル情報をどのようにして電気で表しているのか」という話を統合して考えると「コンピューターとは、電気を利用して表されるデジタル情報を取り扱う機械だ」という風に言い換えることができます。そして、電圧で１と０の状態を表すbitというものが発明され、それと数学の2進法を組み合わせることによって、複数にbitを使うことでもっと大きな数値も表せることが出来るようになったのです。なぜコンピューターを理解するのに2進数を理解しなければならないか、これでお分かりになったでしょうか？

# ほとんどの情報は数値に置き換えて表せることが出来る

ここでは「コード」という概念を考えてみます。「コード」という言葉は、プログラミング教育でも「コーディング・キャンプ」といった言葉でよく耳にしますが、本来の意味としては「あるものを数値で表す」ときのその数値そのものを指して「コード」と呼びます。

例えば、アルファベットのA,B,C,Dなどの文字は65, 66, 67, 68という数値（コード）で表されます。誰がAは65だと決めたんでしょうか？１でもよかったし、20でもよかったんですが、バラバラだと混乱してしまうので「みんなで同じコードを使って表しましょう」ということで、取り決めをしたのです。その取り決めの名前を「American Standard Code for Information Interchange（頭文字を取っ手ASCII)」と呼びます。「アメリカで使う、情報交換のための標準コード」とでも訳しましょうか。アメリカで決められたことですが、世界中でもアルファベット文字に関しては同じ数値を使うようになっています。

では、音声情報や画像情報などの情報はどのようにして数値を使って表すのでしょうか？それらもすべて数値情報として表せますね。音声なら毎秒決まった回数だけマイクから入って来る音の高さや強さなどを数値化して並べたものを記録します。この数値化のやり方にもいろいろな方式があります。技術の進化と共に様々な方法が生み出されました。ASCIIの文字コードと同じように、音声情報のための標準コードもたくさんあります。音声情報を再生するときは、どの標準コードで数値化されたかを調べて、それをもとに原理としては逆方向に情報を変換して、最終的には空気の振動に変換して人間の耳に届くのです。

ということで、コンピューターが取り扱う情報は全て、デジタル情報であり、デジタル情報はbitをたくさん使ってコードという人間が割り当てた数値で表している、そしてbitひとつづつはあくまでも電圧の高い・低いで表されている、ということがお分かりになったでしょうか？「コンピュータと電気」はこういう関わりがあるのです。

# コンピュータに指示を出す命令語も数値化されたコードです

さて、本記事の最後の点として、人がコンピュータに仕事をさせるやり方と、それに電気がどのように関係しているかを考えていきます。コンピュータはデジタル情報を扱えるとありましから、「扱う」という言葉を「処理する」という言葉に置き換えて考えてみましょう。例えば、スマホはコンピューターですが、そのコンピューターに様々な仕事をさせることで人間の生活は楽になりました。「このメッセージを友達A君に送って」っと指示すると、コンピューターは指示通りに実行してくれます。もちろん、WiFiやインターネットやサーバーや相手側の端末など、いろいろなものが関わって初めて実現することですが、スマホだけを見てそれ以外を無視したとすると、スマホは何を指示されたのかをスマホに分かる言葉で言ってあげないと何もしてくれません。

スマホなどのコンピューターの中で頭脳の役割を果たすのがCPUです。実はCPUには何十億ものトランジスタと呼ばれる部品が詰まっていて、そのひとつひとつが１と０の状態をとることが出来ます。さらに、それらは複雑に繋がっていて、その配線だけでもとりだしてまっすぐに伸ばすと数キロメートルの距離になるそうです。そのような賢い頭脳であるCPUでも「何をすればいいのか」全く分かっていません。何をすればいいかを伝えるのは人間の役目です。そこでCPUは「私が理解できる命令のリスト」というのを公表していて、人間はそのリストから命令語を選んで、上手に組み合わせて複雑な仕事をCPUにやらせているのです。そのひとつひとつの命令語も、実は数値で表されているのです。例えば、数値の４を「足し算をせよ」とか、数値の５を「引き算をせよ」といった風に表すことも出来るでしょう。具体的にどのような数値で表すかはCPUを製造するメーカーが決めます。そして、それらの数値のことも「コード」と呼びます。ですから「プログラミング」と同じ意味で使われる「コーディング」とは「CPUの命令語コードを組み合わせる作業」のことを指しているのです。また、「プログラミング」という言葉に含まれる「プログラム」とは、ある目的を達成するひとかたまりのコードのことです。

これらの命令語コードも数値で表してますし、数値はデジタル情報として電圧の状態で表していましたね。それらのコードはプログラムとしてひとまとまりにして保存します。つまりプログラムも電気の力を利用して記録しているのです。プログラミングと電気には、間接的ですが、そのような関わりがあったのです。

# まとめ

「コンピューターと電気」に関して、出来るだけ分かりやすく簡単に理解できるように書きましたが、本当に難しいです。その理由は冒頭でも上げたように「知らなくても済む」ように工夫してあるからです。つまりは「コンピューターと電気」に関する理解は、プログラミングをするためには無くてもいいのです。2進数も、抽象化レイヤーの上でプログラミングをするときは知らなくても何も困りません。

ただ、人間の知の欲求として、もしくは深い総合的な理解の一部として、コンピューターがどのように電気を利用しているのかを納得したいという気持ちは良く分かります。また先生として教える場合も、これをある程度分かっていると、自信をもって教えることが出来るでしょう。