こんにちは､ そしてお帰りなさい｡
プログラムの基本的な話をしよう｡
今回はプログラミングの初級編ということで､ 特にC言語の話をしますが､
プログラミング言語を理解する前に､ プログラムとは何かを理解する必要があります｡
そこで､ C言語の詳細に入る前に､ 基本的な､ 基礎的な概念を説明したいと思います｡
コンピュータは非常に頭の悪い機械です｡
皆さんは､ コンピューターに何ができるのか､ 何をするのか､
十二分にご存じだと思います｡
具体的には､ ブラウザをクリックしたときや､ さまざまなアプリケーションをクリックしたときに､
何が起こっているのか､ つまり､ 何らかのプログラムが動いていて､
そのプログラムがコンピューターに指示を出しているのです｡
コンピューターは本当に馬鹿ですね｡
彼らは言われたことしかやらない｡
つまり､ コンピュータの基本的な操作は､ コンピュータの命令セットと呼ばれるものを形成することになる｡
インストラクション・セットとは､ つまり､ 「どうすれば何かをできるようになるか」ということです｡
だから､
このコンピューターにどうすればいいかを伝える必要があるのです｡
さらに低いレベルのプログラムという形でやっています｡
それぞれのコンピュータには､ 命令セットと呼ばれるものがあります｡
命令セットとは､ 基本的にコンピュータのプロセッサであるCPUに搭載されている命令のことである｡
つまり､ コンピュータを使って問題を解決するためには､ 何をすべきかを指示することで､
この解決策を提供し､ この指示を命令セットに送るのです｡
つまり､ コンピュータのプログラムを書くということは､
特定の問題を解決するために､ CPU（プロセッサ）にコマンドで特定の命令を送るということなのです｡
そして､ その問題を解決するためのアプローチや方法をアルゴリズムと呼びます｡
数学が分かる皆さんにとっては､ アルゴリズムとは問題を解く方法のことですね｡
例えば､ プログラム全体を作成して､ ユーザーが奇数か偶数かを入力するかどうかをテストするだけだとします｡
アルゴリズムと表現されるもの自体がテストであり､ 数が偶数か奇数か､
それがアルゴリズムなのです｡
問題を丸ごと解決する文がプログラムになる｡
そして､ このコンセプトとアルゴリズムについて説明します｡
アルゴリズムは､ さらにモジュールプログラミングに関連したものです｡
ですから､ それについては､ もっと詳しく見るための話をするときにお話しします｡
しかし､ 繰り返しになりますが､ コードを書くときに何をやっているのかを理解してもらいたいと思います｡
一番下の層で何が起こっているのか｡
プログラムの中に入っているこれらのアルゴリズムを書くことになります｡
だから､ プログラムを書くには､ アルゴリズムを実装するための命令をきちんと書く必要がある｡
これらの命令は､ 特定のプログラミング言語のあらゆる種類のステートメントで表現することができます｡
この授業ではc言語を取り上げますが､ iOSアプリケーションではjava､
c++､ objective cなど他のプログラミング言語が使われているのを聞いたことがあると思いますが､
実は今､ Swiftが使われていることが多いんですよ｡
でも､ プログラミング言語を学べば､
アルゴリズムやステートメントという形でCPUに命令を送ることができるようになるんです｡
また､ 基本的な用語として､ CPU､ 中央演算処理装置についてお話したいと思います｡
これがコンピュータの頭脳である｡
ここで､ ほとんどの作業が行われているのです｡
ここで命令が実行される｡
メモリー､ この言葉はよく耳にしますよね｡
そして､ 学生はよくメモリをハードディスクと非常に混同してしまう｡
メモリはハードディスクと同じではありません｡
メモリはラム（Ram）と呼ばれることが多く､ これはランダムアクセスメモリのことです｡
メモリに保存されるデータはすべて､ 別のハードウェアコンポーネントです｡
実際のディスクドライブではありません｡
プログラムのデータはすべて､ 独立したハードウェア部品であるメモリに格納される｡
つまり､ プログラムが動いている間のデータを保存しているわけです｡
そして､ 変数とその意味についてお話します｡
しかし､ プログラムがアルゴリズムを行うためには､ 計算を行うためのデータが必要です｡
そのデータは､ ラム､ メモリに保存されることになります｡
ハードディスクに保存するのではなく､ メモリに保存するのは､
メモリの方がはるかに高速で､ プログラムをより速く実行することができるからです｡
しかし､ メモリは通常､ 再起動しても持続しないので､ もうひとつはっきりさせたいことがあります｡
しかし､ このRAMという言葉だけは理解しておいた方がいい｡
記憶という意味です｡
それは変数と､ プログラム自体のデータが保存されているところです｡
ハードディスクを構成する別の部品は､ 次にハードディスクです｡
ハードウェアドライブは､ コンピュータを購入したときに購入するもので､
永久保存用です｡
これは､ 通常､ 本当に､ 大きなものです｡ ギガバイト､ テラバイトのデータが入っているのです｡
プログラムのリソースとなりうるファイルを格納します｡
そして､ コンピュータの電源を切って入れ直しても､ それらのファイルはそのまま残っているのです｡
プログラムのためにコンピュータの電源を切ったり入れたりすると､ 実際にプログラムの実行が止まり､
ramには何もない状態になります｡
だから､ ラムとハードディスクの違いを理解すること｡
大切なコンセプトです｡
繰り返しになりますが､ ハードディスクが永久保存に関係し､ 私たちが通常そこにリソースを置くように､
ラムはプログラムに関係すると考えてください｡
オペレーティングシステムのファイルや､ さまざまな種類のプログラムリソースがあります｡
オペレーティングシステムは､ 基本的にコンピュータを使用したいときに､ あなたの生活をより簡単にするために開発されています｡
なぜなら､ 非常に低いレベルでは､ コンピュータは言われたことをやっているだけで､
命令セットを使った指示に過ぎないからです｡
このような説明をすべて理解しなければならないとしたら､
とても使いにくいでしょう｡
そこで､ ユーザーがコンピューターを使いやすくするために､ オペレーティングシステムと呼ばれるプログラムがあります｡
コンピュータのすべての動作を制御し､ ハードウェアを介してすべての入出力を処理するため､
キーボード､ マウス､ モニターとのやり取りを理解することができます｡
また､ コンピュータのリソースを管理し､ さまざまなアプリケーションの実行を処理します｡
オペレーティングシステムは完全に別のクラスです｡
OSには様々なものがありますが､ その基本を理解しましょう｡
より簡単にコンピュータを使えるようにするためです｡
一般的なオペレーティングシステムの例としては､ Windowsなどがありますね｡
みんなWindowsを使っている｡
Windows 10でもWindows
XPでも､ 何でもいいんです｡
LinuxやUNIXについては､ C言語の歴史について説明するときに詳しく説明します｡
Androidはモバイル端末用のOS､ iOSは｡
これらは､ 相互作用する多くの異なるプログラムを含むことができる非常に大規模な特定のプログラムであり､
コンピュータとの対話であなたの人生をはるかに容易にします｡
フェッチ実行サイクル｡
これがライフサイクルCPUです｡
ただ､ これも基本的な用語の説明をしているだけなので､
このようなことを申し上げました｡
このように､ コンピュータ､ CPUに命令を送るとき､ 実際にはメモリから命令を取り出しているのですが､
それはプログラムだからです｡
それをCPUで実行するわけですが､ こういうループを何度も何度も繰り返しているんですね｡
繰り返しているんですね｡
また､ ギガヘルツという言葉を聞いたことがあると思いますが､ ギガヘルツのCPUは1秒間に約10億回､
10億回の命令を行うことができます｡
ですから､ このフェッチ実行のライフサイクルを持つコンピュータを実行するときに何が起こっているか､
なんとなく想像がつくでしょう｡
そして､ この効果実行サイクルをもう少し分かりやすく示すために､
インターネット上の画像から取った小さなイラストをご紹介します｡
CPUとこの命令をやり取りしているときに､
何が起こっているのか｡
ラムから取り込んでいるわけですからね｡
そしてラムは､ プログラムデータが入っていることを忘れてはならない｡
そこで指示を出すためにデータを取っているんですね｡
そして､ レジスタやラムに格納されているデータを常にデコードし､
CPUの異なる部分､ つまり制御ユニットかALUで実行するのです｡
それはループですけどね｡
何度も何度も繰り返すだけです｡
そしてまた､ 今のCPUは1秒間に10億回｡
つまり､ cプログラムとcプログラムの書き方について話すとき､ すべての根底にある非常に低いレベルでは､
上位のプログラミング言語を介してCPUとやりとりしているに過ぎないのです｡
つまり､ より高度なプログラミング言語というわけだ｡
より高度なプログラミング言語によって､ プログラムを書くことが容易になります｡
今､ 改めてCPUの命令をすべて理解しなければならないとしたら､
書くのはとても大変です｡
そして､ すべての命令を理解するには､ 通常､ アセンブリ言語であることを意味します｡
アセンブリ言語という言葉を聞いたことがあるなら､ それは単に命令セットを理解するような非常に低いレベルでプログラムを書いていることを意味します｡
そして､ これらの命令をすべて使ってプログラムを書くとしたら､
非常に効率が悪く､ 非常に難しいということは想像がつくでしょう｡
つまり､ 高級プログラミング言語は､ アセンブリ言語の対極にあるわけです｡
もっと高いレベルです｡
例としては､ cが挙げられます｡
C言語は､ より高度なプログラミング言語である｡
プログラムが実行しようとする動作を､ より抽象的に記述したものです｡
CPUの命令を暗記する必要はない｡
言語そのものを理解し､ そのアルゴリズムによって問題を解決していくだけなのです｡
だいぶ英語に似ていますね｡
より分かりやすくなりましたね｡
アセンブリ言語を見ると､ レジスタや数値を使った移動命令､
基本的には数値命令ばかりが並んでいます｡
そして､ cのような高級言語を使うことで､ このような心配は一切ありません｡
命令セットを気にする必要はない｡
アセンブリ言語のステートメントを気にする必要はありません｡
だから､ ずっと効率的で､ 達成感や問題解決もしやすいんです｡
ここでは､ より高度なプログラミング言語としてc言語を学びますが､
他にもjavaやobjective cなど､ さまざまな例を挙げることができます｡
これらは､ あなたの生活をより簡単に､ より効率的にする高水準のプログラミング言語です｡
このような高度なプログラミング言語に加えて､ より抽象的な言語があれば､
その言語をCPU上で実行できるようにしなければなりません｡
本来はCPUが理解できる命令に変換しなければならないのです｡
そこで､ コンパイラの出番となるわけです｡
プログラミングでコードを書くとき､ 多くの場合､ この高級言語であるソースコードを詳細な機械語命令､
基本的にはアセンブリ言語に翻訳するコンパイラを使うことになる｡
つまり､ 高度な､ より抽象的な思考をするプログラムを書こうとするわけです｡
そして､ コンパイラは､ 命令セット上でCPUに送る数百万の命令をすべて生成することになる｡
そこで､ このクラスでは､ まさにこれを実現するためにコンパイラを使用します｡
もっと高度な抽象的な形でソースコードを書いていきます｡
そして､ そのコードをCPUが理解できるように変換するために､
コンパイラと呼ばれるプログラムを実行するのです｡
さて､ コンパイラのもう一つの特徴は､ プログラムが有効な構文を持っているかどうかもチェックすることです｡
だから､ コードを書くときは､ その言語のルールに従わなければならないのです｡
言語のルールとは､ 基本的には構文のことで､ 文の最後にセミコロンをつけるかどうか､
特定のキーワードを使うかどうか､ などです｡
これらを間違えてしまうと､ プログラムを実行することができなくなってしまいます｡
コンパイラはこれらのエラーをすべて見つけて､
「あなたはコードを正しく書いていない｡
そこで､ 一般的な意味でのコンパイラについて､
その使い方､ 理解方法､ 何を教えてくれるのかを知っておこうと思います｡
高級言語は､ 機械語よりもはるかに習得しやすく､ プログラミングもしやすい｡
今､ このスライドの要点は､ c言語のような言語を活用することで､ より効率的で簡単なものになるということです｡
プログラムを書くとき､ 実際には複数の､ 複数のステップを実行することになる｡
そして､ その手順を実に見事に表現したイラストを見つけたのです｡
そこで､ ある本から引用しました｡
どんな種類のプログラムを書くときでも､ 基本的な手順が決まっているのです｡
プログラムの目的を定義する最初のステップから､ 要求事項の理解､
プログラムの維持・修正に至るまで｡
このクラスでは､ このようなことを行っていることがおわかりいただけると思います｡
プログラムを書き始めると､ これらのステップをすべて踏んでいくことになる｡
まず､ プログラムの目的を明確にすることから始めることになります｡
ここで､ 要件を理解することになる｡
何をしなければならないかを理解しなければ､ コードを書き始めることはできません｡
ですから､ このステップで何を達成したいのかを明確にする必要があります｡
要件を理解したら､ 次にコードの設計に入ります｡
コードを設計するとき､ このようにコードを要件に適合させるのです｡
必要だとしたら､ ユーザーインターフェースはどうなるんだ｡
プログラムをどのように構成するのか､ さまざまな関数を作り､
さまざまなアルゴリズムを作ろうとするのか､ などなど｡
そして､ コードの実装を始めるのです｡
これは､ 実際にコードを書いて､ 統合開発環境のエディタに入れるところです｡
設計をプログラミング言語（この場合はc言語）の文法に翻訳し､
c言語のルールを理解するのです｡
ですから､ どんなテキストエディタでも使うことができます｡
実際にコールドブロックというものを使ってみます｡
一般的には､ テキストエディタ以上のもの､ つまりIDEと呼ばれるものを使いたいでしょう｡
コードを書き終えたら､ ソースコードを低レベル言語に変換する必要があるため､
コンパイルする必要があります｡
これはすでにお話したとおりで､ かなり基本的なステップです｡
そして､ プログラムを実行するのです｡ プログラムを実行することは､
それを使うことです｡
そして､ それが第5のステップになるのです｡
なぜなら､ コードを書いて､
それが言語の要件を満たしていても､ 意図したとおりに動作していない可能性があるからです｡
ですから､ プログラムが動いているからといって､ それがうまくいくとは限りません｡
多くの学生から､ おい､ まとめろ､ もういい､ と言われるんです｡ いいえ｡
実行したときに要件を満たしているか､ 思ったとおりに動くかを確認する必要があるのです｡
だから､ 常にテストをしなければならないのです｡
そして､ 1～6のステップを何度も何度も繰り返し行うことになるのです｡
コードを書いて､
テストして､ コードを書いて､ テストして､ コードを書いて､ テストして､ ということを繰り返していることがわかると思います｡
そして､ 通常､ これを行う場合､ 非常に小さな塊で行いたいものです｡
あなたは2行のコード､ テストを書きたいのです｡ さらに2行のコード､
テストなど｡
だから､ テストやデバッグが必要なんです｡
デバッグもコンセプトのひとつです｡
デバッグの講義はたくさんありますが､ これはプログラミングのミスを見つけて修正するときです｡
このようなエラーを発見するために､ ある種のテクニックやツールがあります｡
そして､ テストやデバッグをすることで､ 多くのことを学ぶことができます｡ なぜなら､
常に失敗をすることで多くの情報を得ることができるからです｡
そして､ それが普通になっていくのです｡
コンパイルしても､ プログラムはあなたが言ったとおりに動いてくれないし､
そこから学ぼうとするのです｡
そして､ それをこの授業でやっていくのです｡
正しいやり方を教えるだけではありません｡
間違ったやり方を紹介し､ なぜこれが間違っているのかを見てもらう｡
最後はメンテナンスです｡
これは､ プログラムがリリースされ､ 多くの人に使われるようになったものの､
まだバグが残っている可能性がある場合です｡
ですから､ 例えばウィンドウズ10が発売されても､ まだバグがあったり､ まだクラッシュしたりすることに気がつくでしょう｡
それで､ 常にアップデートを受けることができるのです｡
そして､ そのアップデートを受けることを､ プログラムのメンテナンスと言います｡
ですから､ コードを書き終えて公開したからといって､
メンテナンスが終わるとは限りません｡
プログラムをリリースすると､ 5年､ 10年と世に出る可能性があるため､ メンテナンスはしばしば最も大規模なフェーズ､
最も大規模なステップとなります｡
これらのバグを修正することで､ お客様に喜んでいただくことができるのです｡
また､ 新しい機能を追加して､ 市場で最新の状態に保つこともできます｡
だから､ メンテナンスも本当に大切なんです｡
メンテナンスは､ 製品をお客さまにリリースした後に行われます｡
そのため､ プログラミングの方法論によっては､ これらのステップを飛び越えたり､
異なる順序で実行したりすることがあります｡
これらのステップは､ 必ずしもウォーターフォール方式で､ 最初から始めて最後のステップで終わるとは限りません｡
設計をしてはテストをし､ また設計をし直すといったことを繰り返しているかもしれません｡
だから､ 何が一番実用的かによって､ 全部飛び回ることになるんです｡
私の経験では､ udemyの多くのクラスで､
多くの新人プログラマーがステップ1と2を無視して､ 直接コードを書くことに向かっています｡
コードの書き方は教えてくれるが､ なぜそのコードを書くのかは教えてくれない｡
だから､ これは大きな間違いなんです｡
コードを書き始めるときは､ コンセプトを理解し､ 要件を理解する必要があります｡
また､ 小さなプログラムであればそれで済みますが､
大きなプログラムになると､ デザインに完全に集中する必要があります｡
ですから､ プログラムの規模が大きく､ 複雑であればあるほど､ より多くのプランニングが必要になります｡
コーディングの前に計画を立てる習慣を身につけるとよいでしょう｡
ただ飛び込むだけでなく､ このクラスの講義を見ると､ 私が多くのプランニングをしていることに気づくはずです｡
コードを書き始めたら､ 何をすべきか､ どのように設計すべきか､
課題の中でお伝えしています｡
なぜなら､ これで実際にコードを実装しやすくなるからです｡
これがステップ3です｡
だから､ 紙に書き出すことによって､ 物事を植え付けることができることが多いということを頭に入れておいてください｡
言語をデザインする素敵なドキュメントがいろいろと出ていて､ それを利用することもできます｡
しかし､ 基本的には常に効率的な計画を立てたいものです｡
それから､ 先ほども言いましたが､ これも非常に重要なコンセプトで､
常にスモールステップで作業し､ 分割統治し､ 常にテストすることが必要です｡
100行のコードを書いて､ 「あ､ 終わったからテストに行こう」とはならないようにしたいものです｡
なぜなら､ 今､ もしそれがうまくいかなければ､ 100行のコードのどれかにエラーがある可能性があるからです｡
その問題を解決するのは､ もっと大変なことになりそうです｡
しかし､ 5行のコードを書き､ それをテストし､ さらに5行のコードを書き､ それをテストするというように､
少しずつコードを書いていけば､ 間違いを見つけて修正するのがずっと楽になります｡
だから､ このクラスでコードを書くときは､ 分割統治に力を入れよう｡
お役に立てたでしょうか｡
繰り返しになりますが､ これはあくまで基本的なことです｡
基本的な用語の解説をしたかったのです｡
すでにご存知の方も多いかもしれません｡
しかし､ プログラミング言語を学ぶ際には､ この基本を理解する必要があるのです｡
ありがとうございます｡