こんにちは､ そしてお帰りなさい｡
新しいセクションに入りました｡ このセクションはポインターという名前です｡
おそらく､ このコースで最も重要なセクションです｡
また､ このコースの中で最も難しいセクションでしょう｡ ポインターとcの概念は､
トリッキーで厄介なものです｡
でも､ 本当にゆっくりと進めていくんです｡
たくさんのレクチャーを行い､ 一歩一歩進んでいきます｡
最高レベルのものから､ どんどん細かくしていきます｡
c言語をフルに活用するには､ ポインタを理解する必要があります｡
だから､ とても大切なことなんです｡
そこで､ まずはこのインダイレクトという概念について説明します｡
これは､ 本質的にはポインタと同じ概念です｡
つまり､ ポインターはインダイレクトの概念と非常によく似ているのです｡
あなたは日常生活で間接照明を使用しています｡ ですから､ 例えば､ インダイレクトの意味を説明すると､
会社で何か新しいもの､ 新製品を買わなければならなくなった時のようなものです｡
例えば､ プリンターのインクカートリッジを買い換えたとします｡
もしあなたが大企業に勤めているのなら､ 新しい買い物をするときは､
ある部署を通さなければならないでしょう｡
だから､ 購買部に行くことになるんでしょうね｡
購入の際に誰かに電話して､ 新しいカートリッジを注文してもらうことになるのでしょう｡
そして､ 実際に注文したい商品を扱っているお店を探すのが､
彼らの仕事です｡
そして､ これはどういうことかというと､ 自分で直接その商品を注文しに行くわけではないのです｡
誰かに頼むということですね｡
そして､ 彼らの専門知識と誰がその製品の在庫を持っているかという知識によって､
お客様に製品をお届けするのです｡
つまり､ これはあなたに関する間接的なレベルなのです｡ いきなり店に行って買ってくるのではなく､
まずは店に行ってみてください｡ 購買部に行っても､ その人の部署が知識を持っていて､
全部やってくれるんですね｡
これは､ プログラミングにおけるポインタと同じ概念である｡
プログラミング言語では､ 値そのものではなく､ 名前､ 参照､ コンテナを使って何かを参照する機能のことをインダイレクトという｡
変数名による相互作用の形をとっています｡
データへのアクセスにメモリアドレスを使用することはありません｡
変数名を使っています｡
インダイレクトの最も一般的な形式は､ メモリアドレスを通して値を操作する行為である｡
つまり､ メモリアドレスを表す変数名を使った本当に小さなインダイレクトの記述に加え､
アドレスそのものを使って､ そのメモリアドレスを介して値を操作するのです｡
は､ アドレスそのものです｡
つまり､ ポインターは特定のデータの値に間接的にアクセスする手段を提供するものです｡
値がメモリアドレスである変数であり､ この点を理解することが肝要である｡
ここまで､ ある種のデータ､ 数値､ 文字､ 倍数､
有理数による浮動小数点数を格納する変数を学習してきました｡
今度は､ この種のデータを一切保存しない変数を用意します｡
データストアの種類は､ メモリアドレスです｡
メモリアドレスは16進数の整数で表現されることになりますが､
それでもメモリアドレスであることに変わりはありません｡
つまり､ 既存の変数や動的に割り当てる新しい場所であれば､
アドレスとメモリの別の場所の値になるわけです｡
ですから､ 新しいカートリッジを注文するために購買部を通すことに意味があるのと同じように､
例えばカートリッジが特定のどの店から注文されているかを知る必要はないのです｡
また､ ポインターを使うことには意味があり､ c
アドレス､ メモリアドレスを表すこれらの変数を使用すること｡
メモリアドレスについては､ 講座の一番最初にお話しました｡
また､ プログラムを実行し､ 変数を作成すると､ それらはメモリに保存されます｡
そして､ そのメモリは特定のアドレスを持っています｡ どこかにドライブに行くときに家の住所が必要なのと同じように､
そのデータを取り戻すためには住所を知らなければならないのです｡
ですから､ プログラムの中でポインターを使うことは､ c言語で利用できる最も強力なツールの1つです｡
だからこそ､ 理解することが大切なのです｡
cで実質的なプログラムは､ ポインターを使うことになる｡
だから､ このコンセプトを理解する必要があるのです｡
また､ JavaやCシャープなど､ より現代的な言語をプログラミングしているプログラマーにとっては､
メモリ割り当てやポインタの概念がないため､
必ずしも心配する必要はないでしょう｡
フードの下でも､ javaは参照のコピーを持っているので､
ポインタを使用します｡
同じようなコンセプトですね｡ しかし､ cでは､ 明示的にアドレスを表す変数を持っているのです｡
ポインターは､ c言語で最も分かりにくい概念の一つでもある｡
特に新人プログラマーには､
十分に理解されないまま乱用される傾向があります｡
ですから､ 最初にこの概念を理解し､ より高度なC言語やより高度なポインタの概念に進むにつれて､
何が起こっているのかを明確に把握することが重要です｡
だから､ 最初のうちはこれが理解できなかったら､ 勉強して､
勉強して､ ポインターを使ったコードを書く練習をしてください｡
コンパイラは､ それが指す変数に格納されているデータの種類を知る必要がある｡
つまり､
通常の変数と同じように､ ポインターを作成する際にデータ型を指定する必要があるということですね｡
コンパイラがこれを知る必要があるのは､ 変数と同じ理由で､ あるデータを指していても､
どれだけのデータを割り当てるべきかを知る必要があるのです｡
すべてのポインターは､ 特定の変数型と関連付けられることになります｡
ポインターは､ その型の変数を指すためにのみ使用できます｡
ポインターの定義について説明するときに､ この例を挙げます｡
したがって､ 例えばそれへのポインタ型のポインタは､
int型の変数しか指すことができません｡
繰り返しになりますが､ 変数はアドレスの値を持っています､
それがポインタです｡
そのアドレスは､ メモリのどこかに値を含んでいる可能性があります｡
floatへのポインタ型のポインタはfloat型の変数のみを指すことができる｡
そこで､ ポインターの概念を伝える図解のアイデアを紹介します｡
ここでは､ 構文を気にする必要はありません｡
以前の講義で簡単に説明しましたが､ このアンパサンドとアスタリスクについては､ 必ずしも心配する必要はありません｡
ここで注目してほしいのは､
ポインタはアドレスを持っていて､ そのアドレスは値を含んでいても､ メモリ上のどこか別の場所にあることがあるということです｡
この例では､ 通常の数値を作成していますが､ 100万回作成した後､
ポインタであることを示すアスタリスクが付いたこの構文が表示されていますね｡
その詳細をご紹介していきます｡
また､ アドレスであることを示すアンパサンドも表示されます｡
つまり､ この例では､ int p number型のポインタを作成するときに､
アドレスを代入しているのです｡ なぜなら､ ポインターはアドレスしか保存できないことを忘れてはならないからです｡
そして､ これが実際にどのようにメモリ上にレイアウトされるかというと､
numberという変数があり､ numberは99という値を持っています｡
番号はメモリ上のアドレスも持っています｡
そのメモリ上のアドレスがポインタの値です｡
つまり､ p番号はアドレス1008を指しているポインターです｡
1008の値は99であり､ 変数番号も含まれています｡
これが本当のところなんですね｡ これがはっきりしない場合は､ 1時間くらい見て､
理解してもらう必要があります｡
繰り返しになりますが､ ポイントは､ ポインタはアドレスに値を持つ､
それが格納されていることです｡
そして､ そのアドレスの値に､ ある構文を使って実際にアクセスすることができます｡
では､ なぜポインターを使うのか､ なぜこのような概念を持ち出すのか､ なぜ私たちが使っている既存のデータ型を使い､
文字列を使いたいときには文字配列を使えばいいのではないでしょうか｡
まあ､ 変数だけでデータにアクセスするのは非常に限界がありますからね｡
ポインターを使えば､ 任意の位置にアクセスでき､ 例えばメモリの任意の位置を変数として扱うことができますし､
ポインターを使って演算を行うこともできるので､ より簡単に物事を進めることができます｡
cのポインターは配列や文字列を使いやすくしてくれますが､
それもポインターを使うメリットの一つなので､ これから紹介します｡
ポインターを使うと､ 同じ空間やメモリを複数の位置で参照することができます｡
つまり､ ある場所でメモリを更新すると､ その変更をプログラムの別の場所から見ることができるのです｡
これは､ グローバルなデータを使用しながらも､ 関数の内部でカプセル化するような方法です｡
また､ データ構造内のコンポーネントを共有できるため､ メモリ容量を大幅に節約できます｡
だから､ cが発明されたとき､ 70年代にcが発明されたことを思い出してください｡
cの考え方は､ 非常に効率的であり､ 低レベルであることでした｡
ポインターを介して直接メモリにアクセスする考え方は､
非常に効率的で､
しかも高速です｡
また､ ポインターは､ 関数が変数として渡されたデータを変更することも可能です｡
これは参照渡しである｡ レクチャーを受けることになりました｡
ここで､ ポインターを用いて関数に引数を渡すことができます｡
そして､ 関数の内部で､ そのデータを変更すると､
その変更は関数の外部に反映されます｡
だから､ もうグローバルデータを使う必要はないんです｡
関数の中でデータを使い､ そのデータをポインタとして渡すと､
関数の外でそのデータが割り当てられるのです｡
つまり､
グローバル変数のようにすべてが密結合になるというデメリットがなく､
そのデータを知る必要のある関数だけに限定することができるのです｡
先に述べたように､ プログラムを最適化して､ より速く､ より少ないメモリで動作させることもできます｡
これは､ 特に組み込みのリアルタイムプログラムでは重要な概念です｡
ポインターはまた､ 関数から複数の値を取得することも可能です｡
これまで､ データ関数を渡す方法について､ 関数について説明してきました｡
また､ データを返す方法についてもお話しました｡
今､ 関数から返せる値は1つだけであることが分かっています｡
しかし､ ポインターを使えば､ 実は1つの関数から複数の値を返すことができる｡
そして､ そのことについてお話します｡ それは大きなアドバンテージです｡
また､ 動的なメモリ割り当てについても説明する予定です｡
今､ プログラムのメモリを作るときは､ 変数を宣言するときにコンパイラが暗黙のうちにやってくれています｡
例えばint型の変数を宣言すると､ 自動的にその変数用に4バイトが作成されます｡
配列を使っていて､ 配列のサイズを指定すると､
コンパイル時にそのサイズが確保されます｡
だから､ それ以上のデータを保存しようとすると､ プログラムが動かなくなるんだ｡
しかし､ 実際に実行時に必要なだけのメモリを作成する機能があれば､
それは大きな意味を持つでしょう｡
そして､ ポインターはこれを可能にします｡
これらは､ 実行時の動的な､ メモリ割り当てでメモリを作成することができます｡
これについても､ すべてお話しする予定です｡
ポインターを使うことで､ より複雑なデータ構造を設計・開発することができます｡
そして､ データ構造とは､ データを格納するものである｡
データ構造の例としては､ スタック､ キュー､ リンクリストなどがあります｡
そして､ ポインターを使えば､ もっと簡単にそれらを作成することができます｡
ポインターは､ メモリへのダイレクトアクセスを実現し､ ここでも効率的な高速化を実現します｡
だから､ ポインターは大きな概念になるんです｡ ポインターの講義が多くなりますね｡
これらの概念は､ C言語を理解する上で重要かつ不可欠なものですから､ 皆さんには集中して､
私がこれらの概念について話すときに注目してほしいのです｡
では､ 頑張って､ 始めましょう｡ ありがとうございます｡