C言語-関数ポインタ

関数ポインタについて

関数ポインタとは

関数ポインタとは、関数が格納されたメモリアドレスを指すポインタを意味します。

C言語では、関数は実行時にメモリ上に配置され、関数名をメモリアドレスとして扱うことができます。

関数を呼び出す際に、関数ポインタを関数が格納されたアドレスに設定することで、呼び出す関数を任意に変更することが可能です。


関数ポインタの利用

関数へのポインタ宣言は、以下の形式となります。


戻り値の型 (*変数名) ();

関数へのポインタを用いて、関数を呼び出すには以下のように呼び出します。


(*ポインタ名)(引数...);

以下のサンプルでは、関数アドレスを表示して、実行します。


#include <stdio.h>

static void
func(const char *str)
{
    printf("%s\n", str);
    return;
}

int
main(void)
{
    void (*func_p)();
    func_p = func;
    printf("func address = %p\n", func_p);
    (*func_p)("function pointer.");
    return(0);
}

関数ポインタの呼び出し関数の切り替えサンプルプログラム

関数ポインタ登録リスト(テーブル)の利用

引数に関数名を指定することで、呼び出す関数を変更することが可能です。

関数識別名と関数名をリストアップしたテーブルを作成しておき、関数識別名によって呼び出す関数を変更するプログラムを記述します。

(なお、以下のプログラムではエラー処理を省略しています。)


#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>

/* 関数ポインタ実行用定義 */
struct cmd_exec{
    char *name;
    int  (*func)(int argc, char *argv[]);
};
typedef struct cmd_exec cmd_exec_t;

/* 関数プロトタイプ */
static int add(int argc, char *argv[]);
static int sub(int argc, char *argv[]);

/* 関数ポインタの登録リスト(テーブル) */
static cmd_exec_t cmd_list[] = {
    {"add", add},
    {"sub", sub},
    {NULL, NULL}
};

static void
usage_exit(char *cmdname)
{
    printf("usage: %s [add|sub] x y\n", cmdname);
    exit(EXIT_FAILURE);
}

int
main(int argc, char *argv[])
{
    cmd_exec_t *cmd = NULL; 
    int rc = 0;

    if(argc != 4) usage_exit(argv[0]);

    /* コマンド実行 */
     for(cmd=cmd_list; cmd->name!=NULL; cmd++){
       if(strcmp(argv[1], cmd->name) == 0){
            rc = cmd->func(argc, argv);
            printf("return = %d\n", rc);
            break;
        }
    }
    exit(EXIT_SUCCESS);
}

static int
add(int argc, char *argv[])
{
    return(atoi(argv[2]) + atoi(argv[3]));
}

static int
sub(int argc, char *argv[])
{
    return(atoi(argv[2]) - atoi(argv[3]));
}

実行例

第一引数に「add」を入力して、整数を2つ渡すとadd関数を実行します。


$ ./sample add 4 3
return = 7

第一引数に「sub」を入力して、整数を2つ渡すとsub関数を実行します。


$ ./sample sub 4 3
return = 1

第一引数に関数識別名以外の文字列を入力して実行しても、処理を行いません。


$ ./sample mul 4 3
$ 

関連ページ