*C言語* 〜38時限目〜 関数ポインタの仕組みについて・・・
〜目次〜
関数ポインタの仕組みについて
さらに高度なポインタの使い方について学んでいきます。
関数の処理内容は、
機械語のコードに翻訳されます。
プログラムが実行される時には、
この機械語のコードがメモリに格納されることになっています。
コンピュータはメモリ上にある、
機械語のコードを1つずつ取り出して、
処理をするようになっているのです。
このため、
関数はメモリ上のアドレスというものを持っています。
関数のアドレスとは、
関数の処理の先頭部分のメモリの位置をあらわしたものです。
この「関数アドレス」を、ポインタに格納して使うことができます。
このようなポインタのことを、
関数ポインタ(function pointer)
と呼びます。
関数ポインタを宣言する
関数ポインタと言っても、
これまでのポインタと使い方は同じです。
関数ポインタは以下のようにして宣言します。
戻り値の型(*関数ポインタ)(引数リスト);
例で、
int (*pM) (int x, int y);
のような関数ポインタを宣言したとします。
「pM」が、指定した形式の関数のアドレスを、
格納することができるポインタです。
変わった形式での宣言に見えるが、
いままでのポインタの宣言と同じ方式です。
関数のポインタは「*ポインタ」の部分を( )で囲むので、
注意をしてください。
囲まないと、
演算子の優先順位の関係で、
pM(int x, int y)という関数を宣言したことになります。
関数ポインタにアドレスを格納する
ポインタにアドレスを代入することで、
はじめて、メモリ上の変数の位置をさし示すことができるようになりました。
意味のないアドレスが格納されている場合には、
ポインタを使うことはできません。
関数ポインタも関数のアドレスを格納する必要があるのです。
以下のようにして、関数のアドレスを格納します。
関数のアドレスは、「関数名」であらわします。
&はつける必要がありません。
関数ポインタ = 関数名;
このようにして、
関数の処理内容が格納されている、
メモリの先頭位置をさし示すことになります。
変数をさし示すポインタに、
間接参照演算子*を使うことで、
その変数の内容を間接的に扱うことができました。
関数の場合も同じです。
関数ポインタに間接参照演算子を使うことで、
関数を間接的に扱うことができます。
すなわち、関数を呼び出すことができるようになります。
関数ポインタを利用する。
実際に関数ポインタを使った、
プログラムを入力してみます。
sample86.c
ーsample86の実行画面ー
1番目の数値を入力してください。
7
2番目の数値を入力してください。
10
最大値は10です。
sample86は、
関数ポインタを宣言し、関数のアドレスを代入しています。
さらにポインタを使って関数を呼び出しています。
実行画面をみてわかる通り、
関数はちゃんと呼び出されています。
関数ポインタを使うことで、
関数を間接的に呼び出すことができるのです。
関数ポインタを応用する
単純に関数を呼び出すのであれば、
関数ポインタを使わないで、関数を直接呼び出す方が簡単です。
関数ポインタを使って便利な時は、
その配列を作成したときに、
便利なプログラムが書けるようになります。
実際に以下のコードを入力してみて見てください。
sample87.c
ーsample87の実行画面ー
どこに行きますか?(0:アメリカ 1:フランス 2:イギリス)
1
フランスです。
sample87では要素数が3の配列を宣言しています。
各関数のアドレスを代入することで、
配列の各要素が3種類の関数をさし示すようにしています。
ユーザーが入力した数値によって、
どの関数を呼び出すか決めています。
関数ポインタを使わずに、
同じような処理をすることもできるが、
コードが複雑になります。
同種類の関数を多く宣言する際には、
関数ポインタを使うことで、便利に書くことができます。
〜END〜