アリスはC言語のポインタを学ぶ
そもそも、いまさらC言語を学ばないといけないのか? という疑問はあるものの、コンピュータを扱うプログラム言語としてC言語は重要な位置を占めているので、避けて通れない。特にC言語で悩ましいのが "ポインタ" の問題である。C言語を学ぶといきなり、ポインタの話が出てきてしまうのが難点でもあり、障壁でもある。
たとえば、Java とか C# とか Python とか JavaScript のようなプログラム言語では、数値を表示するときに次のように書く。
```c#
int a = 10;
Console.WriteLine(a);
```
この表示は「10」が画面に表示される。Java とか JavaScript でも似たように書くことができる。
「10」というのは数値であって、いわゆる値というやつである。値ってのは何だ、ってことなのだが、まあ、10 とか 100 とか 3.14 とか、そういう数値のことを示していると思えばよい。もちろん、数値としての「10」と、ここに印刷されて...モニタならば画面に表示されてということになるのだが...いる「10」というものは、実は別ものである、というややこしい話は別の機会にしておこう。ソシュールの現象学だとかヴィトゲンシュタインの言語ゲームだとかチョムスキーの生成文法とかウンベルト・エーコの完全言語論とか、まあ、いろいろとあるのだが、ここでは割愛しておこう。話がややこしくなるので。
さて、「10」という数値を表示させているが、これだけだと味気ないので、「a の値は 10 です」と表示させるようにしよう。C# ならば次のように書く。
```c#
int a = 10;
Console.WriteLine($"a の値は {a} です");
```
お? 何かやらややこしい書き方が出て来たな? ということになる。なにやら2つの「"」(ダブルクォート)で囲んである中に、a が2つある。最初の「a の値は」の部分は、多分「a の値は」を表示することを示しているのだろう。最後の「です」も同じである。では、途中にある「{a}」は何か? これは「a」というアルファベットを示しているのではなく、その前の行に書いてある「int a = 10;」の「a」を示している。
ここで注意したいのは、「int a = 10;」で書かれている「a」と「a の値は」中にある「a」とは異なるのである。いや、見た目は同じだから、どちらも「a」なのだが、意味が違う。いや、次元が違うのだ。
「int a = 10;」で書かれている「a」は、C言語のプログラムの世界にある a である。そして、Console.WriteLine の中にある「a の値は」は、我々が見ているモニタ越しに映る a という文字を示している。もちろん、モニタには一見すると a が書かれているように見えるのだが実は違う。液晶モニタであれば、実は RGB のドットの集まりであって a という形をしているだけである。だから、モニタの前にいる読者にとっては a という形をしている何らかのものを a という文字として認識している、という現象になる。このあたりがよくわからなくなるのがゲシュタルト崩壊ということになるのだが話がややこしくなるので割愛しておこう。特に、ソシュールの現象学でありシニフィエとシニフィアンの話にもなるのだが脱線が過ぎるのでこれも割愛しておこう。
さて、仮にモニタに移っている a という形のものを、読者が a という文字で認識したとき、プログラムの中にある「{a}」は何を示しているのか? ということになるのだ。
ここが奇妙なところで、プログラムのコードというものと、実際にプログラムを動かしたものとは異なるということである。つまり、プログラムのコードである Console.WriteLine なんとかは、プログラムを動かすと何処かに消えてしまうのだ。いや、消えてしまうのではなく、いったん中間言語というものに変換されて、その中間言語を実行時に VM が読み取って動かす、ということになるのだが、これもコンピュータの動作原理ということになるので割愛しておこう。
そこで、「{a}」が何に変換されるかというと、プログラムが実行されるとモニタ越しには「10」になる。そうすると、ひとつながりになって「a の値は 10 です」と表示されるわけである。繋がらない場合はどうなるのとか、モニタが狭い場合にはどうなるのかというややこしい話もあるのだが、これも割愛しておこう。モニタが極端に狭い場合は「a の値は」の部分で切れてしまうかもしれない。そうなると、うしろに続いている「10 です」が見えなくなってしまう。実は、そこにはあるのだが見えないという怪奇現象が発生してしまうのだ。いや、あるけど見えないのだから超常現象ともいえなくもない。
ここで、次のプログラムを見ておこう。
```c#
var a = "a";
Console.WriteLine($"a の値は {a} です");
```
さらにややこしくなっているが、これは「a」という変数の中に「a」という文字をいれておいて、Console.WriteLine 関数で表示させているのである。さらに「a の値は」に引き続き「{a}」があるので、ここの部分が切り替わって「a」になる。だから、モニタには「a の値は a です」と表示されるわけである。なんだ、a が a なんだから当たり前じゃないか。「a = a」ということだな、と賢明な読者は納得するであろう。実に正しいのである。
これはプログラムのコードではなく、論理の問題であり、「a = a」が正しいと証明できるわけである。プログラムコードという低層から、モニタ越しの高層に至るまでに、正しさが保たれているという好例であろう。
実にすばらしいことである。
さて、ここでC言語の話に戻ろう。C# というプログラム言語では「a = a」という証明ができたのだが、かつてのC言語はどうだったであろうか?
```c
char *a = "a";
printf("a の値は %s です\n", a);
```
C言語では、「a = a」を証明しようとするときに、何故か「%s」というものを使わねばならない。さらに言えば、「char *a = "a";」という書き方をして「*」という奇妙な記号を使わないといけないのだ。
つまりは、これがポインタだ。「*」はポインタである「ここが重要ポイントですよ」という目印になる。ほら、本を読んでいるときによく脚注を書くために「*」とか「**」とか「*1」とか使うじゃないか。あれと同じだ。ここでも目印として「*」を使って後から解説しますよ、という意味をつけておくのだ。
その解説の部分が printf 関数の中にある「%s」と「a」の組み合わせである。C# であれば「{a}」と書くこともできたのだが、C言語の場合はあまり直感的な形而上学的な話ができなかったので「%s」と「a」を分離させていたのである。つまりは、まだ人間は天使の天上界にはいけなかったのだ。これは、シュタイナーの天使学に通じるものである。しかし、昨今では菩薩の世界が広がっているところから、菩薩への道筋と天使への道筋が重なってきているといってもいい。つまりは、プログラム言語からコンパイラそして実行形式という道筋がきれいに整備されているということなのである。
ここに来て「a」という文字を「alice」という名前に変えておこう。コンピュータ業界では文字に対して文字列(string)という言い方をするのだが、ちょっと無粋なのでここではやめておきたい。文字が連なったものを文字「列」という形になるのだが、それは文字の繋がり、つまりアルファベットの組み合わせを示していることになるのだが、漢字文化圏の人達にとっては理解不可能とも言える。いわば「私」であり「我」というひと文字で示されている大量の言葉があり、それらを「文字列」という形で示すのは違和感があるからだ。だから、「alice」という「名前」つまりは、指示語に変えてしまおうというわけである。
これをC言語を使って現わそう。
```c
char *alice = "alice";
printf("alice は %s です\n", alice);
```
「alice は alice です」と表示されるわけである。実にすばらしいことである。alice は alice であり、それは同定される人物ということだ。そこにいるアリスは、まぎれもなくルイス・キャロルの愛したアリスであり、ちょっとした不機嫌さを持ちつつも、そのわずかに得られる笑みを得るためにルイスは物語を書き上げるのである。アリスの眉が少しだけ歪むとき、ルイスは、そんな悲しい顔を眺めつつも、再び興味深い笑顔が差し込むことによってルイスの気持ちは倍増していくのである。
そう、なにかの興味深さとちょっとした知的好奇心がアリスの心を動かす。ゆえにルイスは、更にC言語のコードを書き変えるのである。
```c
char *alice = "bob";
printf("alice は %s です\n", alice);
```
alice と bob は秘密を共有してルイスを追い出してしまう。ああ、なんと悲しいことだろうか。もう、永遠にアリスの心はルイスに届かない。
【完】
プラダの鞄を直接あげるのが値渡し https://www.moonmile.net/blog/archives/1431 そのうち、値渡しと参照渡しの話は書く予定。




