Menu
Coddy logo textTech

関数ポインタの宣言

CoddyのCジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 33/61。

ここまで、struct の埋め込みを使って継承をシミュレートする方法を学びました。しかし、同じ呼び出しに対して異なるオブジェクトが異なる応答をする真のポリモーフィズムには、さらに function ポインタが必要です。

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

構文は最初は難しそうに見えるかもしれません。function pointer を Declare するには、return の型を指定し、次にアスタリスクを付けた括弧内に pointer の名前を記述し、その後に parameter の型を続けます。

int (*operation)(int, int);

これは、2つのintパラメータを受け取り、intを返す任意のfunctionを指すことができる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 parameters を受け取り、それらの積を返す
    • subtract: 2つの int parameters を受け取り、最初の値から2番目の値を引いた結果を返す
  2. main で、2つの int parameters を受け取り、int を返す関数を指せる、operation という名前の関数ポインター変数を宣言します
  3. 3つの入力、つまり2つの整数と operation code(multiply の場合は1、subtract の場合は2)を読み取ります
  4. operation code に基づいて、適切な関数を operation ポインターに割り当てます
  5. 割り当てられた operation の名前を出力し、その後、ポインターを通じて関数を呼び出した結果を出力します

3つの入力、つまり最初の数値2番目の数値、およびoperation code(1または2)を受け取ります。

出力は次のようになります。

Operation: multiply
Result: 35

ここで、multiply は operation の名前です(code が2の場合は subtract)。35 はポインターを通じて関数を呼び出した結果です(この場合は、5 × 7)。

覚えておきましょう。関数ポインターを宣言するには、return type、アスタリスクを付けたポインター名を括弧で囲んだもの、および parameter types が必要です。関数を割り当てるには、括弧を付けずに関数名だけを使用します。

自分で試してみよう

#include <stdio.h>

// TODO: ここに multiply 関数を定義する


// TODO: ここに subtract 関数を定義する


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

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

オブジェクト指向プログラミングのすべてのレッスン

自分で練習してみよう: Cオンラインコンパイラ