Menu
Coddy logo textTech

関数ポインタの宣言

CoddyのCジャーニー「Object Oriented Programming」セクションの一部 — レッスン 33/61。

これまで、構造体の埋め込み(struct embedding)を使用して継承をシミュレートする方法を学んできました。しかし、異なるオブジェクトが同じ呼び出しに対して異なる応答をするという、真のポリモーフィズムを実現するには、さらなる要素、つまり関数ポインタ(function pointers)が必要です。

関数ポインタは、関数のアドレスを格納する変数です。通常のポインタがデータのアドレスを保持するのと同様に、関数ポインタは実行可能コードのアドレスを保持します。

構文は、最初は難しく見えるかもしれません。関数ポインタを宣言するには、戻り値の型を指定し、次に括弧で囲んだアスタリスク付きのポインタ名を指定し、その後にパラメータの型を続けます:

int (*operation)(int, int);

これは、2つの int 型の引数を取り、int 型を返す任意の関数を指すことができる、operation という名前の変数を宣言します。*operation を囲む括弧は非常に重要です。これらがないと、ポインタを返す関数を宣言することになってしまいます。

このポインタに関数を割り当てるには、単に関数名(括弧なし)を使用します:

int add(int a, int b) {
    return a + b;
}

int (*operation)(int, int);
operation = add;  // これで operation は add を指すようになります

関数名は、そのアドレスとして機能します。明示的に &add を使用することもできますが、これはオプションです。C言語ではどちらの形式も同等です。

challenge icon

チャレンジ

簡単

関数ポインタの宣言と、それらへの関数の代入を練習しましょう。関数ポインタが異なる算術関数を保持できる、シンプルな数学演算システムを作成します。

以下のプログラムを作成してください:

  1. 2つの関数を定義します:
    • multiply — 2つの int 型パラメータを受け取り、その積を返します
    • subtract — 2つの int 型パラメータを受け取り、1つ目から2つ目を引いた値を返します
  2. main 関数内で、2つの int 型パラメータを受け取り int を返す関数を指すことができる、operation という名前の関数ポインタ変数を宣言します
  3. 3つの入力(2つの整数と、1つの演算コード(1は multiply、2は subtract))を読み取ります
  4. 演算コードに基づいて、適切な関数を operation ポインタに代入します
  5. 代入された演算の名前を出力し、次にポインタを介して関数を呼び出した結果を出力します

3つの入力を受け取ります:最初の数値2番目の数値、そして演算コード(1または2)です。

出力は以下のようになります:

Operation: multiply
Result: 35

ここで、multiply は演算名(コードが2の場合は subtract)、35 はポインタを介して関数を呼び出した結果(この例では 5 × 7)です。

ヒント:関数ポインタを宣言するには、戻り値の型、括弧で囲まれたアスタリスク付きのポインタ名、およびパラメータの型が必要です。関数を代入するには、括弧を付けずに関数名のみを使用します。

チートシート

関数ポインタは、関数のアドレスを格納する変数であり、同じポインタを介して異なる関数を呼び出すことを可能にすることでポリモーフィズムを実現します。

関数ポインタの宣言

構文では、戻り値の型、括弧内のアスタリスク付きのポインタ名、およびパラメータの型を指定します。

int (*operation)(int, int);

これは、2つの int 型のパラメータを受け取り、int 型を返す任意の関数へのポインタとして operation を宣言します。*operation を囲む括弧は必須です。

ポインタへの関数の代入

括弧を付けずに関数名を使用します:

int add(int a, int b) {
    return a + b;
}

int (*operation)(int, int);
operation = add;  // operation は add を指すようになります

関数名は、そのアドレスとして機能します。明示的に &add を使用することもできますが、これは任意です。

自分で試してみよう

#include <stdio.h>

// TODO: ここで multiply 関数を定義します


// TODO: ここで subtract 関数を定義します


int main() {
    int num1, num2, code;
    
    // 入力を読み込む
    scanf("%d", &num1);
    scanf("%d", &num2);
    scanf("%d", &code);
    
    // TODO: 2つの int 型パラメータを受け取り int 型を返す関数を指すことができる、
    // 'operation' という名前の関数ポインタを宣言します
    
    
    // TODO: 操作コード(1は乗算、2は減算)に基づいて、
    // 適切な関数を operation ポインタに割り当てます
    
    
    // TODO: 操作名と結果を出力します
    // フォーマット:
    // Operation: <name>
    // Result: <result>
    
    return 0;
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

Object Oriented Programmingのすべてのレッスン