6/2(火)〜4(木) の学習ログです(主にC言語)
こんにちは。
いつもありがとうございます。
自分の未熟さによって人の面子を立てられなかった時に、
自分の未熟さを憂うよりも、まず先に相手や周りのことを考えて悩める人間になりたい安藤です。
つまりは、そんな時も失敗自分に目が向いてしまうわけです。
文字通り足りない人間なので修行中です。死ぬまで修行です。
けれども、反省も大切なことだけど、そこに執われていては自分中心ヤローのままになってしまうので、失敗した分、誰かに喜んでもらえるように今日も頑張っていきたい思います。
こんな回もあります。笑
このようなことも私の人間性の一部分なので恥ずかしいけど載せてみました。
ということで、学習ログを残していきます。
2020.6.2(火)
◎C言語(web記事「苦しんで覚えるC言語」)
●ポインタ変数の仕組み
・モードの切り替え
ポインタ変数は2つのモードがあり、何も指定せずにポインタ変数を使っている場合は、ポインタ変数モードになる。
通常変数モードに切り替えるには、変数の前に*記号をつける。
*記号がついたポインタ変数は通常変数と全く同じ機能になる。
通常変数モードに切り替わったポインタ変数は通常の変数と同じように機能するが、
その時に使われるメモリはポインタ変数モードの時に代入されたアドレス。
つまり、ポインタ変数モードの時に読み書きしたいメモリのアドレスを代入して、その後、
通常変数モードに切り替えてそのメモリを操作する。
というのがポインタ変数の最も基本的な使い方。
直接、何番のメモリを書き換えろ、と指定するのではなくて、
書き換えたいメモリのアドレスを代入し、モードを切り替えて書き換える、という
2段階になっている。なので直感的には分かりにくい。
「*」記号は、3通りの意味を持っている。
1つ目は、乗算演算子。
2つ目は、間接参照演算子。ポインタ変数を通常変数モードにする。
3つ目は、ポインタ変数を宣言する時に使用する。
通常変数モードに切り替える間接参照演算子と、宣言時に使用する*は何の関係もない全く別の記号。
この3つには全て別の文字を使う方が分かりやすいはず。同じ文字を割り当てているのは、C言語の欠陥の1つ。
ポインタの本当の使い方は、ショートカットとして使用する。
デスクトップに並んでいる、あのショートカットと同じ。
ショートカットは指し示すファイル自体ではないので、ショートカットはどこにでも自由に作ることができる。複数作ったり、削除しても指し示すファイル自体には影響はない。
これこそがポインタの役割そのもの。
そのポインタ変数が使える場所であれば、元の変数が使えない場所であっても、ポインタ変数を通常変数モードに切り替えれば、元の変数と同じように使うことができる。
まさにショートカットのような働きをさせることができるわけ。
一般的にポインタは、C言語とC++のみの機能と言われている。
指定したメモリのアドレスを操作するという意味ではその通り。
しかし、ポインタの本当の使い方はショートカットとして使うことなので、その観点では、実用的な言語のほとんどにポインタはある。
Javaの「参照」はまさにそんな機能で、しかも頻繁に使われるし、
Visual BasicのSETステートメントなども同様の機能。
そもそもポインタがないのでは、連結や木構造などの複雑なデータ構造を実現できないし、オブジェクト指向も困難。
その意味では、仕組みが不明なJavaやVisual Basicのポインタより仕組みがはっきりしているC言語のポインタの方が理解しやすい。
他の言語の参照と、C言語のポインタの最大の違いは、自動なのか、手動なのか、ということ。
他の言語の参照はほとんど自動でショートカットとして機能するようになっているが、C言語のポインタは完全に手動で、プログラマが完全に理解した上で使わなければならない。
ただ、上級者がC言語のポインタを使いこなすとポインタだけで、ほぼあらゆる制御構造、あらゆるデータ構造を実現できる強力な機能となる。
実際、C言語の様々な機能ってほとんどポインタで成り立っていると言っても過言ではないらしい。
◎読書「王様達ヴァインキング」より
・ランサムウェア
PC内のデータを暗号化、使用不能にして「人質」にする不正プログラム。
データ復旧と引き換えに「身代金」を要求する。
2020.6.3(水)
◎C言語(web記事「苦しんで覚えるC言語」)
●ポインタ変数の仕組み
引数による情報の受け渡し
・ポインタ型の引数
C言語では、関数へ情報を渡す場合、元の変数の値のコピーを渡す。
この方法のことを「値渡し」と呼び、元の変数の値が変更されないことが特徴。
ポインタ型の引数であっても、値のコピーが渡される。
ポインタ型を使うのは、ポインタ型はアドレスを受け取ることができるから。
関数を呼び出す時に、既に存在する変数のアドレスを指定すると、関数で受け取ったアドレスをポインタ変数に代入すれば、あとはポインタ変数を通常変数モードに切り替えて、返ってきた情報が代入される。
返された情報は呼び出し側で指定した変数に記憶されていることになる。
ポインタ変数にアドレス値が代入されている場合には、通常変数モードに切り替えてそのメモリを自由に読み書きできるのだから、結果として、呼び出された関数から呼び出し元の変数の中身を書き換えることができる。
&付きで呼び出していた関数は全て同様の仕組み。
C言語では、この使い方が最もポピュラー。
2020.6.4(木)
◎C言語(web記事「苦しんで覚えるC言語」)
●ポインタ変数の仕組み
引数による情報の受け渡し
・配列型の引数
配列を渡すのではなく、配列の先頭のアドレスを渡している。
配列の先頭のアドレスを渡すので、要素数は全く関係ない。
呼び出された関数における配列は、呼び出し元と同じメモリ領域を指すことになるので、呼び出された関数で配列の値を変えると呼び出し元も変更される。
・配列のような使い方
[ ] は、配列の要素番号を指定する演算子。
その仕組みは、配列名というアドレスに足し算を行なっているだけ。
つまり、配列でなくても、アドレス値なら何でも良いということ。
数式の中に配列名を記述した場合、 [ ] の記号の有無に関わらず、
配列名は、配列の先頭要素へのアドレス(ポインタ値)として扱われる。
そして、その配列名に[ ] をつけた場合、そのアドレスに番号の値だけ足し算を行い、
その結果として、足し算された分の番号の要素として扱われる。
・宣言時と数式との違い
配列を宣言する時には、[ ] で要素数を指定し、配列の要素を使う時は、 [ ] で番号を指定するのですが、実はこの2つは全く別の記号。
宣言時の[ ] は要素数を指定するという意味を持つが、
数式の中で使う [ ] はアドレスに足し算する演算子。
C言語では、似た使い方には、同じ記号を使いたがる傾向があり、そのため異なる意味に同じ記号を割り当てている部分が多いみたいっす。
このことから、使えるメモリならばポインタ変数を配列のように使えることが分かる。
・配列とポインタは全く別物
配列とは、多数の変数を順番をつけて、まとめて扱う方法であり、
ポインタとは、変数のショートカットを作る方法。
それなのに似たような使い方ができるのは、配列の設計と関係がある。
それは、C言語では配列を実現する手段としてポインタを利用しているから。
従って、ポインタ変数では、配列と同等のことができてしまう。
そのため、配列とポインタは混同しやすい。
配列はあくまで多数の変数の先頭を示す固定された変数であり、
ポインタ変数は好きな変数のアドレスを代入して、好きなメモリ領域を使うことができる可変的な変数。
今回はこれで以上です。
最近学習に割り当てる時間が少ないので、もっと頑張りたいです。
とは言っても、できる時はできるし、できない時はできないし、仕方がないこともたくさんあるので、気負わず緩まず継続して、少しでもコツコツやっていきます。
あ、あと、C言語は動的言語の仕組みを知るにはすごい良い教材だと思います。
それでは、また来週の火曜日に!