TPY ENGINEERING VLOG

TPY ENGINEERING VLOG(C,JAVA)

*C言語* 〜38時限目〜 関数ポインタの仕組みについて・・・

〜目次〜

  

 

 

関数ポインタの仕組みについて

さらに高度なポインタの使い方について学んでいきます。

関数の処理内容は、

C言語のプログラムをコンパイルした時に、

機械語のコードに翻訳されます。

プログラムが実行される時には、

この機械語のコードがメモリに格納されることになっています。

コンピュータはメモリ上にある、

機械語のコードを1つずつ取り出して、

処理をするようになっているのです。

このため、

関数はメモリ上のアドレスというものを持っています。

関数のアドレスとは、

関数の処理の先頭部分のメモリの位置をあらわしたものです。

この「関数アドレス」を、ポインタに格納して使うことができます。

このようなポインタのことを、

関数ポインタ(function pointer)

と呼びます。

 

関数ポインタを宣言する

関数ポインタと言っても、

これまでのポインタと使い方は同じです。

関数ポインタは以下のようにして宣言します。

戻り値の型(*関数ポインタ)(引数リスト);

例で、

int (*pM) (int x, int y);

のような関数ポインタを宣言したとします。

「pM」が、指定した形式の関数のアドレスを、

格納することができるポインタです。

変わった形式での宣言に見えるが、

いままでのポインタの宣言と同じ方式です。

関数のポインタは「*ポインタ」の部分を( )で囲むので、

注意をしてください。

囲まないと、

演算子の優先順位の関係で、

pM(int x, int y)という関数を宣言したことになります。

 

関数ポインタにアドレスを格納する

ポインタにアドレスを代入することで、

はじめて、メモリ上の変数の位置をさし示すことができるようになりました。

意味のないアドレスが格納されている場合には、

ポインタを使うことはできません。

関数ポインタも関数のアドレスを格納する必要があるのです。

以下のようにして、関数のアドレスを格納します。

関数のアドレスは、「関数名」であらわします。

&はつける必要がありません。

関数ポインタ = 関数名;

このようにして、

関数の処理内容が格納されている、

メモリの先頭位置をさし示すことになります。

変数をさし示すポインタに、

間接参照演算子*を使うことで、

その変数の内容を間接的に扱うことができました。

関数の場合も同じです。

関数ポインタに間接参照演算子を使うことで、

関数を間接的に扱うことができます。

すなわち、関数を呼び出すことができるようになります。

 

関数ポインタを利用する。

実際に関数ポインタを使った、

プログラムを入力してみます。

sample86.c

f:id:YuyaTerayama:20180913131137p:plainーsample86の実行画面ー

1番目の数値を入力してください。

7

2番目の数値を入力してください。

10

最大値は10です。

sample86は、

関数ポインタを宣言し、関数のアドレスを代入しています。

さらにポインタを使って関数を呼び出しています。

実行画面をみてわかる通り、

関数はちゃんと呼び出されています。

関数ポインタを使うことで、

関数を間接的に呼び出すことができるのです。

 

関数ポインタを応用する

単純に関数を呼び出すのであれば、

関数ポインタを使わないで、関数を直接呼び出す方が簡単です。

関数ポインタを使って便利な時は、

その配列を作成したときに、

便利なプログラムが書けるようになります。

実際に以下のコードを入力してみて見てください。

sample87.c

f:id:YuyaTerayama:20180913202112p:plainーsample87の実行画面ー

どこに行きますか?(0:アメリカ 1:フランス 2:イギリス)

1

フランスです。

sample87では要素数が3の配列を宣言しています。

各関数のアドレスを代入することで、

配列の各要素が3種類の関数をさし示すようにしています。

ユーザーが入力した数値によって、

どの関数を呼び出すか決めています。

関数ポインタを使わずに、

同じような処理をすることもできるが、

コードが複雑になります。

同種類の関数を多く宣言する際には、

関数ポインタを使うことで、便利に書くことができます。

 

〜END〜