関数ポインタ

提供: MonoBook
移動: 案内検索

関数ポインターとは、関数ポインターである。

英語読みについて[編集]

日本語でいう「関数」はプログラミング言語によって「ファンクション(function)」だったり「メソッド(method)」だったりと曖昧なので、英語での呼び方も「function pointers」だったり「method pointers」だったり「functors」だったりと様々である。よって名称・呼称の細かい違いは気にしてはならない。時間の無駄である。

概要[編集]

関数ポインタは関数変数のように扱えてうれしいという物である。

主に絶望的なほど巨大な分岐処理を、関数ポインタのLUTに置き換えてることでソースコードを単純化するなどという場面で使われる。ゲームなどではよく多用される技法である。

また、コールバック関数と呼ばれる使われ方もある。たとえばWindowsなどのいわゆるイベントドリブン実装では、何かしらのイベント発生時に関数ポインタ変数がNULLではなかったら関数コールバック関数)を実行する、などという使われ方をしている。

記述例[編集]

C言語[編集]

C言語系のプログラミング言語では実引数が一致していなくても怒られないことが多い。そのため、その扱いには注意を要し、一歩間違えればバグの温床となる。

#include <stdio.h>
 
static int func(int a)
{
    printf("func: %d\n", a);
    return 2 * a + 3;
}
 
int main(void)
{
    int (*f1)(int a) = func;
    int result = (*f1)(10);
 
    printf("main: %d\n", result);
    return 0;
}

Pascal[編集]

元祖Pascalにはそもそもポインタ自体がない。よって関数ポインタもない。

Turbo Pascal[編集]

Turbo PascalにはPointer型という名のポインタが追加されている。

program Test;
 
uses
  Classes;
 
type
  TFuncPointer = function(a : Integer):Integer;
 
function Func(a : Integer):Integer;
begin
  WriteLn('Func: ', a);
  Func := 2 * a + 3;
end;
 
var
  ptr : Pointer;
  ret : Integer;
begin
  ptr := @Func;
  ret := TFuncPointer(ptr)(10);
  WriteLn('Main: ', ret);
end.

C#[編集]

C#は見た目こそC言語似だが、その実態はTurbo Pascalの方言であるため、基本はTurbo Pascalに右に倣えである。

C#では関数ポインタはオブジェクト指向プログラミング言語として、同一インスタンス内のフィールド変数プロパティ参照できるなど、若干の改良が加えられており、その名称も「デリゲート」と改名されている。名称と微妙な機能の差はあるが基本は同じである。

using System;
 
class App
{
    delegate int FuncDelegate(int a);
 
    static int Func(int a)
    {
        Console.WriteLine("func: {0}", a);
        return 2 * a + 3;
    }
 
    static void Main()
    {
        var f1 = new FuncDelegate(Func);
        int result = f1(10);
 
        Console.WriteLine("main: {0}", result);
    }
}

関連項目[編集]

参考文献[編集]