こんにちは､ そしてお帰りなさい｡
この講義では､ ポインタが指す値にアクセスすることについてお話したいと思います｡
そこで､ ポインタを思い出してください｡
ポインタは､ メモリアドレスを格納しています｡
そのメモリアドレスには､ 実はどこかの値が入っている｡
そして､ ポインターはそのメモリアドレスを指すわけです｡ それが指し示す値を取得したい｡
なぜなら､ アドレスになるポインタの値をプリントアウトするだけなのですが､ アドレスを取得したいからです｡
つまり､ ポインタが指すアドレスの値には､ インダイレクト演算子を使ってアクセスすることができるのです｡
インダイレクト演算子はアスタリスクである｡
アスタリスクを使ってポインタを宣言する方法を学びましたが､
アスタリスクを使ってポインタが指している値を見つける方法も学びます｡
つまり､ ポインタをデリファレンスするために使うので､
デリファレンス演算子とも呼ばれるわけです｡
例えば､ 15に等しい数値があったとして､ int型を宣言してint型を指すポインタを作り､
アンパサンドを使って数値のアドレスを代入するのです｡
さて､ ポインタが指している値をどのように取得するのでしょうか｡
デリファレンスができる｡
このポインタが指す値は､
基本的に15です｡
つまり､ ポインタ変数には､ 変数番号のアドレスが格納されているわけです｡
これを式の中で使って､ 結果の新しい値を計算することができます｡
例えば､ ポインタの指す値に5を足した値を結果にしたいとします｡
ポインターの名前の前にそれ用のアスタリスクを使用することになります｡
つまり､ ポインター変数が指しているのは､
5を足した15であると言うことです｡
そのポインタが指しているアドレスが何であるかということです｡
つまり､ 間接演算子アスタリスクは乗算に使われる記号でもあり､
ポインタ型を宣言するときにも使われるのです｡
だから､ これは非常に混乱する｡
必ずしも何が起こっているのか､ コンパイラがどのように動作しているのかを知るにはどうしたらいいのでしょう｡
まあ､ 文脈の問題なんですけどね｡ そのアスタリスクをいつ使うか､ どこで使うかによる｡
ポインタの型の直後に宣言するときにアスタリスクを使えば､
明らかに宣言を使用していることになります｡
2つの数字の間にアスタリスクを使うなら､
掛け算に使われていることになる｡ そして､ 例えば右側や左側のポインタ名の直前で使われている場合は､
値の代入や値へのアクセスが行われることになります｡
つまり､ このインダイレクト演算子を使うときは､ 文脈が重要なのです｡
といった具合です｡
コンパイラはそう解釈するんですね｡
この例では､ スターポインターで､ 前にデータ型がないか､
両側に2つの数字がない場合､ インダイレクトポインター､
デリフェレンスであることがわかります｡
では､ 例を挙げて説明しましょう｡ ここでは､ 10に等しい整数のカウントを作成する別の例を示します｡
また､ xという型の整数を別の変数に作成することにしています｡
countを10に初期化し､ xは何もない状態に初期化しています｡
次に､ int型ポインタを作成します｡ データ型の後にアスタリスクをつけて､
int pointerという名前をつけているので､
intポインターであることがわかります｡
これから､ そのintポインタにcountのアドレスを代入します｡
なぜなら､ ポインターはアドレスを値として含むだけでなく､ 何かを指し示していることを忘れてはならないからです｡
つまり､ ポインタが指すアドレスが何であれ､ 変数xに代入することができるのです｡
だから､ xは実際に10を表示することになる｡
10. そこで､ count percent d ird
x percent irdと表示すると､ countは10になり､ xは10になる｡
そうやってポインタをデリファレンスして､ その値を得ることができるのです｡ ポインタの値を表示する場合は､
ポインタがメモリ上の値を持っていることを覚えておいてください､
それは単なるアドレスです｡
では､
16進数の整数とアドレスで表されるポインタの値を表示したい場合はどうすればよいのでしょうか｡
まあ､ 形式指定子パーセントpを使えばいいんだけどね｡ 以前にもお話したことがあります｡
ポインタの値を16進数でメモリアドレスとして出力します｡
というのも､ ポインタの宣言で何かを代入しないときは､
必ずそれをnullに初期化するのが良い習慣だからです｡
そして､ 数字の変数10を割り当てます｡
そして､ そのポインタをnumberのアドレスに代入する｡
つまり､ p数という値は､ 実はアドレスになるわけです｡
というアドレスがあります｡ だから､ もしプリントアウトしようとしたら､ パーセントpを使い､ それがアドレスの値になる｡
もし､ それが指しているものをプリントアウトしたければ､ インダイレクト演算子を使って参照を解除しなければならない｡
しかし､ アドレスをプリントアウトすると､ どうなるかというと､ 16進数でプリントアウトされます｡
ポインターはメモリ上で8バイトを占有し､ アドレスは16進数で表示されます｡
では､ その仕組みはどうなっているのでしょうか｡
まあ､ お使いのマシンが64ビットアドレスと32ビットアドレスのどちらをサポートしているかによりますが｡
もしあなたのマシンが64ビットOSなら､ 16桁の16進数で表示されることになります｡
もし､ あなたのマシンやOSが32ビットアドレスしか持っていない場合､
16進数は8桁で表されることになります｡
さて､ 住所を表示する場合はどうするか｡
ポインタには値があるのだから､ 何が違うのかと言われるかもしれません｡
しかし､ オペレーターのアドレスと一緒に表示することも可能です｡
そこで､ この例では､ 番号のアドレスを表示したいと思います｡
Numberはポインターではありません｡ Numberは単なる整数です｡
そのアドレスを取得する場合は､ アンパサンドを使用します｡
そのアドレスを表示させたい場合は､ またパーセントpを使えばいいだけだ｡
アンパサンドを適用するだけです｡
そのため､ ポインタ変数にアンパサンドを供給すると､ 実際にはそのポインタのアドレスが表示され､
ポイントの値は表示されないことになる｡
ポインタのアドレスは､ メモリ上のあるアドレスであることを忘れないでください｡
ポインターの値は､ それが指し示すアドレスです｡
そして､ それが指し示す値は､ メモリ上の別の場所にあります｡
そこで､ ポインタの働きを説明した図を思い出してください｡
ポインタを宣言すると､ そのポインタのためのメモリが8バイト作成されます｡
そのポインタの値がアドレスとなる｡
そして､ そのポインタの指す先が､
通常は指定された型の値である｡
しかし､ 実際には3つのパートがあることを忘れないでください｡
p番号のアドレスをプリントアウトする場合は､ 再びアンパサンドを使用します｡
それが実際のポインタのアドレスになる｡
そして､ 警告を回避するためにボイドスターを使用することになります｡
つまり､ ポインタ自体にもアドレスがあり､ 他の変数と同じように､ 宣言したときに割り当てられることを覚えておいてください｡
アドレスを表示するための変換指定子として､ パーセントpを使用します｡
アンパサンド演算子 the address of 演算子を使って､ 変数 p number
が占めるアドレスを参照します｡
それがポインタのアドレスです｡ そしてまた､ ポインタはアドレスの値を持っている｡
キャスト a void はコンパイラからの警告を防ぐためで､ 具体的にはパーセント
p 仕様では値がある種のポインタ型であることを期待します｡
しかし､ アンパサンドナンバーの型は､ それのポインタである｡
で､ それをキャスティングするわけです｡
ポインターが使用しているバイト数を表示する｡
ポインターの情報を取得するもう一つの方法です｡
ここでは､ sizeof演算子を使用することができます｡ 異なるデータ型バイトを表示するためのsizeof演算子について学びました｡
ポインターを使っても同じことができます｡
私が実行しているマシンでは､ これは8バイトを占めます｡
そして､ 64ビットOSなのでマシンアドレスは64ビットです｡
また､ この方法で sizeof を使用すると､ コンパイラの警告が出ることがあります｡
sizet は実装で定義された整数型です｡
この警告を防ぐには､ 次のように引数をint型にキャストすればよいでしょう｡
つまり､ p数サイズ､ パーセントdバイトと言うことです｡
そして､ intと言い､ inch sizeof pの数値にキャストするのでしょう｡
これは､ メモリ上のポインタのサイズ､ そのアドレスのポインタのサイズ､ つまり､
ほとんどのシステムでは8バイトであることを示しています｡
それは､ アドレスを含んでいるだけだからです｡
ここでもう一つ例を挙げます｡ これはいろいろなものが表示されますね｡
そして､ この例を実行して､ 出力を表示します｡
ただ､ 実行する前に､ ここで何が起こっているのかを少し説明したいと思います｡ 宣言された数字があるんです｡
ポインターがNULLに初期化されているんです｡
numberの値を10に設定しました｡
そして､ 整数のアドレスをプリントアウトし､
その値をプリントアウトするという､ 非常にシンプルなものです｡
演算子のアドレスをやるときは､ パーセントpをやるんです｡
そして､ そのポインタにnumberのアドレスを代入するのです｡
そして､ ポインターの情報をプリントアウトすることになります｡
ポインタのアドレスそのものを出力したいのです｡
パーセントp､ ボイドスターアンパサンドナンバーを使えばいいんです｡
そのポインタが何バイトのメモリを持っているかを確認したいのです｡ sizeofと言える｡
ポインタの実際の値､ つまりアドレスが知りたいのです｡
余計な情報を入れずに､
ただp数と言って､ パーセントpを使うことができるのです｡
ポインタの指す値､ つまりアドレスの値を見たい場合は､
スターpナンバー､ インダイレクト演算子を使用します｡
そして､ p数がinを指していることがわかるので､ パーセントdと言うことができるのです｡
では､ この例をコードブロックにして､ 実際にどのように表示されるかを見てみましょう｡
アドレスを表示するときは16進数で表示し､
それ以外のときは値で表示します｡
だから､ これは見覚えがあるはずだ｡ これは､ ポインタの異なる部分にアクセスする方法を紹介しているだけのプログラムです｡
ここでも､ 通常の数値データ型であるintと､ ポインタを用意しました｡
nullで初期化します｡
まず､ 10という数字を表示します｡ つまり､ これはnumberのアドレスを表示し､
10行目と11行目にnumberの値を表示するということですね｡
そして､ ポインタであるnumberのアドレスを代入することになります｡
ポインタの実際のアドレスを知りたい場合は､ アンパサンドと演算子のアドレスを使って､
void starにキャストすればよいのです｡
パーセントPを使用しています｡
もし､ ポインタが何バイトのメモリ上にあるか知りたい場合は､ percent d sizeof を実行します｡
もし､ ピーナッツ・ポインタのアドレスと値を見たい場合は､ パーセント p をして､
p 数と言えばいいのですが､ p 数はアドレスだからです｡
ポインタの値の中にあるアドレスの値で､ ポインタが何を指しているかを確認したい場合は､
アスタリスクp番号と言って､ 間接参照演算子を解除すればいいのです｡
では､ これを実行してみましょう｡
これを実行すると､ 最初に2つのものがプリントアウトされます｡
6行目にある数字のアドレスで､ これは16進数で0060ff0cというものです｡
そして､ これは実際には32ビットのプログラムを実行しているので､ 8ビットしかないのがわかりますね｡
は､ 10という数値の変数です｡
そして､ 実際に割り当てられたメモリへのポインタのアドレスをプリントアウトする｡
番号とは別の住所です｡
なぜなら､ これはポインタに割り当てられたアドレスだからです｡
ポインタ番号のサイズは4バイトで､ 32ビットアドレッシングということになる｡
ポインタの値､ つまり数値のアドレスは同じであるべきで､
それは0060ff0cです｡
そして､ 実際に名前､ パーセントpのついたポインタを使うだけで､
数字のアドレスを得ることができることがわかります｡
オペレータのサイズは4バイトと見た｡
p numberが指している値（10）を取得したい場合は､ インダイレクト演算子を使って参照を解除する必要があり､
10と表示されることがわかります｡
しかし､ アドレスを表示するときはパーセントpを使い､
整数ポインタの値やバイト数を表示するときはパーセントeを使うことがわかりますね｡
つまり､ これがポインタ値にアクセスするための基本的な構文です｡
ポインタのアドレス､ アンパサンド､
ポイントが指す値､ ポインタ自体はただの変数名､
そしてポインタが指す値にはインダイレクト演算子を使用します｡
ありがとうございます｡ お役に立てれば幸いです｡ これを研究し､ 実行するのです｡