こんにちは､ そしてお帰りなさい｡
この講義では､ ポインタの定義､ 主にレポーターを宣言する構文､ そして､ ポインタにメモリアドレスを割り当てるための演算子address
ofを使うことについてお話したいと思います｡
というわけで､ ここまでで､ ポインタとは､ メモリアドレスを指す､
あるいはメモリアドレスを値として含む変数にほかならないことを頭に叩き込んでおいたはずだ｡
つまり､ ポインタを宣言することは､ 通常のポインタを作成することとは異なるのです｡
だから､ ポインタポインタのようなことはできない｡
それはポインタの宣言の仕方ではありません｡ 構文が若干異なります｡
アスタリスクを使うんですね｡ だから､ 変数がポインタであるというだけでは不十分なのです｡
また､ ポインタが指す変数の種類を指定する必要があります｡
変数の種類によって､ 使用するストレージの容量が異なります｡
ポインタ操作の中には､ その記憶サイズを知る必要があるものもあります｡
ですから､ 通常の変数でデータ型を指定するのと同じように､
ポインターのデータ型の変数を作るときにも､ そのデータ型を指定する必要があるのです｡
int 型の変数へのポインタを宣言するには､ 次のようにします｡ int
star またはアスタリスク p 数｡
それがポインターであることを教えてくれそうです｡
intは同じように見えますが､ その後にアスタリスクがあります｡
アスタリスクはポインタであることを意味し､ 次にポインタ自体の型を指定する｡
int型ポインタです｡
変数名 p numbers int star の変数の型｡
int 型の任意の変数のアドレスを格納することができる｡
ポインターはアドレスを格納します｡ つまり､ 他の変数のアドレスを格納する場合､
その変数は整数型として定義されなければならないのです｡
つまり､ PIはint型変数､
char star
pcは文字型変数､ float star pf star pgはfloat型変数へのポインタである｡
それは､ あなたがどう定義しているか､ タイプの問題です｡
アスタリスクとポインター名の間のスペースは任意です｡
そこにスペースを入れる必要はない｡ スペースはなくても大丈夫です｡
これから変数の再参照について説明しますが､
通常､ 宣言ではスペースを使い､ 再参照するときにはスペースを使いません｡
そのため､ これらの宣言には､ 慣習的にすべてスペースが含まれているはずです｡
ポインタの値はアドレスなので､ ほとんどのシステムでは内部で符号なし画像として表現する必要があります｡
だから､ やはり何かを保存する必要があるのです｡ 偶然にも16進数の数値が格納されているのです｡
また､ 整数のように見えるように保存していても､
整数型と思わないでください｡
整数でできることがポインタでできるとは限らないし､ その逆もしかりです｡
だから､ プリントアウトしようとすると､ 16進数の数字に見えても､ 整数のように扱えるわけではありません｡
例えば､ ある整数と別の整数を掛け合わせることはできますが､
あるポインタと別のポインタを掛け合わせることはできません｡
ポインターは本当に新しい型です､ 整数型ではありません｡
パーセントpはポインタに指定されたフォーマットを表します｡
ポインターのさまざまなデータを表示し､ それがどのように使われるかを見て行くことにします｡
前の宣言は､ 変数を作成しますが､
初期化は行いません｡ そこに課題はない｡
ポインタには常に値を割り当てる必要があり､
初期化を行わないと非常に危険です｡
そこで､ ポインタを宣言するときに初期化するようにしたい｡
他の変数のアドレスでない場合､ あるいは動的にメモリを割り当てなかった場合､
何を初期化すればよいかわからない場合は､ ヌルポインタを使用することができます｡
そこで､ ポインタを初期化して､ 何も指し示さないようにすることができます｡
これは､ nullを使用して行います｡
intへのポインタに対して､ instar p number equals nullと言いますね｡
Nullは､ 標準ライブラリで定義されている定数です｡
ポインターのゼロに相当します｡
何も指し示さないということです｡
メモリ上の任意の場所を指さないことが保証されています｡
なぜなら､ 誤ってバッファオーバーフローを起こしたり､ 書き込んではいけないメモリに書き込んだりするようなミスを犯さないようにするためです｡
このように初期化することで､ 実際に起こりうるいくつかのミスを制限することができます｡
以前､ NULLについて少しお話しました｡ ヌルキャラの話をしました｡
その概念は､ ヌルポインターとは異なります｡
ヌルポインターは､ 何も指していないことを意味し､ そのように初期化されるべきです｡
標準defのincludeディレクティブを追加する必要があります｡ ここでnullの定義を使用したい場合はhを使用します｡
オペレーターの住所です｡ もし､ ポインターをアドレスに代入したかったら､
既存の変数のアドレス演算子を使えばいいのです｡
つまり､ すでに宣言したaddやsubの変数で変数を初期化する場合は､
演算子のアドレス､ アンパサンドを使う｡
これは､ scanf関数の説明のときに見たことがありますね｡
ここでは､ 整数値の変数99を代入しています｡
int型のポインタを作成して､ それにnumberのアドレスを代入しています｡
これは､ numberがintであり､
作成したポインタもintを指しているためです｡
つまり､ 等号演算子の後にすることは､ アンパサンドを使うことだけなのです｡
そして今､ p numberはnumberのアドレスを含むことになります｡
p番号の初期値は､ 変数番号のアドレスとなります｡
メモリが割り当てられていないものをポインタに代入することはできないので､
数値の宣言はそのアドレスを格納するポインタの宣言より先に行わなければなりません｡
そのポインタに番号を割り当てようとすると､ 後で実行しない限り､ 番号は存在しない｡
ポインタにアドレスを割り当てるには､ そのアドレスにメモリが割り当てられている必要があります｡
さもないと､ コンパイラから文句を言われる｡
しかし､ ポインタの宣言には何も特別な意味はないので､ 注意が必要です｡
通常の変数とポインタを同じステートメントで宣言することができます｡
だから､ double値､ p値f numと言える｡
この文では､ 2つ目の変数p valだけがポインターで､
他の2つはただのダブルです｡
それは､ その宣言の中で､ もう少し明確に､ わかりやすく表現されています｡
しかし､
スターpqで言うとどうでしょう､ これは両方ともポインタであることを意味し､ そうではありません｡
int型ポインタはpだけで､ 変数qはint型です｡
pもqもポインタだと思うのはよくある間違いです｡
ですから､ 同じ行で多くの変数へのポインタを宣言する場合は注意が必要です｡
また､ ポインター名としてpで始まる名前を使用するのも良いアイデアです｡
これは､ 見ただけで､ その変数がポインタであることを教えてくれます｡
ですから､ 通常はプログラムの先頭､ 通常はmain関数の中で変数の宣言をすべて行います｡
そして､ プログラムの後半でこれらの変数が使われているのを見ると､
接頭辞にpがついているので､ 異なるデータ型や異なるポインタ型を簡単に識別することができます｡
この講義では､ ポインタを定義して宣言し､
既存の変数のアドレスをポインタに代入する方法について説明しました｡
さて､ 既存の変数に必ずしもポインタの値を代入したくない場合もありますし､
新しいメモリを確保したい場合もあるでしょう｡
それらについては､ この後の講義でお話しする予定です｡ でも今は､ シンプルに考えています｡
ここでは､ ints型のポインタとdoubleやfloatのような異なる簡単な型を使用することに焦点を当てます｡
そして､ 既存の変数､ アドレスの割り当てに集中し､
それがどのように機能するかを確認するつもりです｡
では､ 前に進みましょう｡ ありがとうございます｡