Saturday, November 7, 2020

ポインタについて、すごく雑にしゃべる

 まず、そもそもITデベロッパーがポインタを学ぶ必要あるのか問題というのがあり、こういうのは隠されていてもう気にする必要ないとかいろいろ言われているけど、まあ知らないメリット何?という話ではあるし、そもそもCのソースを読めないと大体の古典的(かつ今でもよく使わせていただいている)ソースを読むことができない。

ポインタの概念は基本難しいものではないのだが、初学者が独学でCと結びつけて、Cの記法と1対1対応で追っかけているから挫折するのではないか、とも思われる。

まず、Cを追いながら解説する。

まず、

Array<String> val = "hello"

くらいなら(これはCじゃないな)どんなウェブ系エンジニアでもわかるであろう。

要は文字列の配列ってことだ。

string[] val = "hello"

こうも表記できる。

だが、Cではそもそも文字列っていうまとまった概念がない。そういう世界観がないから、もっと高級言語から入った初学者は混乱するわけだが、

Cは char型データの配列として文字列を理解している、すなわち


char [] val = "hello"; ... 1

みたいなかんじだ。

ちな、

h e l l o \0

の6文字が hello を構成していて、最後の \0 は文字データの終わり(null)ということだ。(改行の\nとは区別される)


同時に、(ここが大事なのだが、) 上記 1. は

char *val = "hello"; ... 2

とも表記できる。 この場合、 優先順位的にカッコをつけてわかりやすくすると


(char *)val = "hello"; ... 2


こうなってて、つまり char型のポインタの配列が valだよってことになる。

そして、このポインタのあつまり(配列)だ、というのは、自動的にポインタはデータの一番はじめ(あたま、てっぺん)をさす。つまりhからはじまる。

Cの場合処理と評価式とかがごっちゃごちゃにまじるし、インクリメントが処理の主役を担っているようなこともあるので注意が必要だが、なれるとそんなに苦しくはない。

malloc(size) とかで場所取りをするのは今回はあまり詳しくは触れないが、メモリを確保して、使ったらリリースしてあげる。Javaではこういうのは、JVM内のヒープに対してGCがやってくれている。がCでは自分でやる必要がある。

また、

char **val

みたいなアステリスクが2つある場合は2重配列を暗に意味しており、

さらに、それぞれの要素の大きさが固定でないという意味で、

char [x][y]

みたいなスタック配列の定義の仕方よりも環境に優しい、とはいえる。

コンパイル後のオブジェクトファイルっていうのは一部アドレスが定義されておらず、linkerによってはじめて補完されてバイナリになるし、実行時にしかわからないアドレスもある。これらはバイナリの仕様上仕方がないものである。

また、free list というのがあり、これは circular linked list? のようなものだが空いているメモリ領域をうまく活用するために用意されているデータ構造でも、ポインタが当然のように使用されている。ポインタというのは意外といろんなところの基礎に食い込んでおり、概念として逃げるというのはやはり難しい。


まあそんなかんじでだらだらとしゃべってみた。

No comments:

Post a Comment