とくにあぶなくないRiSKのブログ

危ないRiSKのブログだったかもしれない。本当はRiSKだけどググラビリティとか取得できるIDの都合でsscriskも使ったり。

『三田典玄の「体育館の裏話」 - 関数の話(7)』につっこむ

多分,今までで一番破壊力がある。

関数を定義するときは、通常は

int function(int parameter1,int parameter2)
{
(関数の中身の記述)
}

とするわけだが、このとき、function()という関数の定義とともに、functionという名前の変数も一緒に定義される。そして、そのfunctionという変数には、function関数へのポインタが入っている。

「functionという名前の変数も一緒に定義される」
「functionという名前の変数も一緒に定義される」
「functionという名前の変数も一緒に定義される」
「functionという名前の変数も一緒に定義される」
あなたはいったい何を言っているんだ???
「そして、そのfunctionという変数には、function関数へのポインタが入っている。」
「そして、そのfunctionという変数には、function関数へのポインタが入っている。」
「そして、そのfunctionという変数には、function関数へのポインタが入っている。」
「そして、そのfunctionという変数には、function関数へのポインタが入っている。」
あなたはいったい何を言っているんだ???

一方、関数へのポインタだけが入る変数である「関数へのポインタ型」の変数を定義することもできる。この場合は、このように定義する。

int (*f)(int x,int y);
この宣言で、「f」という名前のポインタ変数(関数へのポインタ変数型)が定義される。

「関数へのポインタ変数型」というものは(少なくとも)C言語には存在しません。

x,yのある括弧内はパラメータの部分を指す。そして、この関数へのポインタfが指し示す先の関数はx,yというint型の2つの引数を持つ。

x, y でなくても構いません。引数の名前は氏が好きな省略が可能です。

次に、このfに、先ほど定義したfunction()関数の関数へのポインタを代入するには、以下のように書く。
f = function;
で、

「function()関数の関数へのポインタ」は意味不明です。「function関数へのポインタ」です。

この「f」のポインタ変数にある関数を呼び出すには、

C言語の指摘なのか日本語の指摘なのか分からなくなってきました。『この変数「f」が指す関数を呼び出すには,』です。

以下の書式を使う。
a = (*f)(x,y);
で、なんでこんなまどろっこしい方法で関数をわざわざポインタ変数で表現して使うのかというと、

a = f(x,y);
で呼び出せます。間接演算子* を適用する意味は全くありません。あなたが無意味なことをしてまどろっこしくしているだけです。
関数へのポインタに間接演算子を適用して関数にしても,その関数が再び関数へのポインタに成り下がり*1,その関数へのポインタに対して関数呼出し演算子() が適用されます。
a = (************************************f)(x,y);
とか,有名な話。

要するに変数として関数を扱える、ということは、関数の引数として関数を渡す、ということができたり、関数の戻り値として関数を返す(?)ことができたり、

関数と関数へのポインタは別物です。関数型言語のように関数を返すことはできません。C言語で『 m を受け取って,「n を受け取って n を m 倍した値を返す関数(あるいは関数へのポインタ)」を返す関数』をさらっと,あるいは美しく書けますか? とか大げさな事を言ってみるテスト。(この辺,詳しい人に怒られそう...)

関数のポインタ変数の配列を作ることによって、関数の配列を作ることができたり、要するに「関数」を、「変数」のように扱うことができるからだ。

え?それって・・・

え?それって・・・と、思った方は鋭い。まさに、プロシージャとデータが同列に扱える、という「オブジェクト指向」そのもの、なんだな。

鋭い私も「日本語でおk。」と言わざるをえない。

そして、この関数が構造体に「ポインタ変数として」登録できる、ということになるから、つまりはそれが「クラス」ということになる。

にほんごでおk。

実は、C言語ってのは、その言語をよく知っている人にとっては、それができた最初から「オブジェクト指向」的プログラミングが可能になっていたのだ。

「的」は不要だと思う。

しかし、話は逆で、これまでC言語オブジェクト指向的な書き方をしていたプログラマがもっと簡単に「オブジェクト指向」を実現できるといいね、と、C言語をなおしたものが、「C++」とか「Objective-C」なんかのオブジェクト指向C言語なんだな。ということで、

C言語をなおしたものが,オブジェクト指向C言語…。あっているのか間違っているのか分からない。私にとって難解な日本語だ。

「関数へのポインタ」ができる、ということは、単にそれだけにとどまらない、大きな可能性を持ったプログラミングへの入り口だったわけだ。

「関数へのポインタ」ができる…。どういう意味だろ?
<追記>
C言語でも関数へのポインタを用いて多態を実現できます。これを「オブジェクト指向」的プログラミングと呼んでいるのか否かは分かりません。氏の日本語が難解なので。もし,単に構造体のメンバに関数へのポインタを持たせただけでクラスと呼んでいるのであれば乱暴すぎです。C++Objective-Cに謝るべきです。
</追記>

(続く)

続くらしい。


(続く)

*1:結果,初めのfと全く同じになる。