8
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【C言語】関数ポインタの基礎

Last updated at Posted at 2021-01-04

この記事では,関数ポインタの基礎的な使い方について解説したいと思います.

関数もアドレスを持っている##

関数も変数と同じようにメモリ領域に保存されているので,アドレスを持っています.
まずは,そのことを確かめてみます.

# include <stdio.h>

int main(void){
    printf("%p\n", main);
    return 0;
}
実行結果
0x563c3dc4c64a 

実行結果は環境によって異なりますが,関数名が関数のアドレスを表していることがわかりました.

関数ポインタの宣言##

関数ポインタは以下のように宣言することが出来ます.

戻り値の型 (*ポインタ変数名)(引数情報);

これだけではよくわからないと思うので,例を見てみましょう.
例えば,2つの整数の内,大きい方の整数を返す関数int max(int, int);を保持するポインタp_func の宣言をしてみます.

int (*p_func)(int, int);

関数ポインタの使い方##

まず,関数ポインタへ関数のアドレスを代入します.最初に確認したように,関数名が関数のアドレスを表しているので以下のように代入を行えます.

p_func = max;  //ポインタ変数名 = 関数名

次に,関数の呼び出しです.

(*p_func)(3, 5);

関数ポインタを間接参照することによって,p_funcに代入されている関数maxを呼び出すことができます.
もっと簡単に呼び出すこともできます.

p_func(3, 5);

1つめの呼び出し方の方がポインタを使っている感じはしますが,こちらの方が簡単でいいですね.

まとめ##

ここまでに説明したものをまとめたものが以下のプログラムになります.

# include <stdio.h>

int max(int a, int b){
    int max = a;

    if (max < b)
        max = b;
    return max;
}

int main(void){
    int (*p_func)(int, int);

    p_func = max;
    printf("(1)(*p_func)(3, 5) = %d\n", (*p_func)(3, 5));  //(1)
    printf("(2)p_func(3, 5) = %d\n", p_func(3, 5));        //(2)
}
実行結果
(1)(*p_func)(3, 5) = 5
(2)p_func(3, 5) = 5

おまけ(関数ポインタと配列)##

関数ポインタは配列と組み合わせて使用されることが多いです.if文やswitch文などの処理分岐をする必要がなくなり,簡潔にプログラムを書けるようになることがあるからです.
以下のようにすると,関数ポインタの配列を宣言できます.

戻り値の型 (*ポインタ変数名[配列の要素数])(引数情報);

先ほどの例で言うと,次のようにします.

int (*p_func[2])(int, int);

同じ戻り値の型,引数の関数しか格納できませんが,それぞれの要素に関数のアドレスを格納して使います.
最後に例を示しておきます.

# include <stdio.h>

int max(int a, int b){
    int max = a;

    if (max < b)
        max = b;
    return max;
}

int min(int a, int b){
    int min = a;

    if (min > b)
        min = b;
    return min;
}

int main(void){
    int (*p_func[2])(int, int);

    p_func[0] = max;
    p_func[1] = min;
    for (int i = 0; i < 2; i++)
        printf("p_func[%d](3, 5) = %d\n", i, p_func[i](3, 5));
}
実行結果
p_func[0](3, 5) = 5  //maxが呼び出されている
p_func[1](3, 5) = 3  //minが呼び出されている
8
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?