関数を引数として渡す
CoddyのCジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 36/61。
関数ポインターの最も強力な用途の1つは、他の関数に引数として渡すことです。これにより、コードを変更せずに関数へカスタム動作を注入できます。この手法は、コールバックと呼ばれることがあります。
2つの数値に対して計算を実行する関数について考えてみましょう。操作をハードコーディングする代わりに、実行する操作を定義する関数ポインタを受け取ることができます。
typedef int (*Operation)(int, int);
int compute(int a, int b, Operation op) {
return op(a, b);
}compute関数は、それが加算をしているのか、減算をしているのか、それともまったく別の処理をしているのかを知りません。渡された関数をそのまま呼び出すだけです。
int add(int a, int b) { return a + b; }
int multiply(int a, int b) { return a * b; }
int main() {
printf("%d\n", compute(5, 3, add)); // 出力: 8
printf("%d\n", compute(5, 3, multiply)); // 出力: 15
return 0;
}同じ compute 関数が、渡す関数によって異なる結果を生成することに注目してください。このパターンは、柔軟で再利用可能なコードを書くうえで基本となります。構造を一度だけ記述し、関数の利用者が必要とする具体的なロジックを提供します。
チャレンジ
簡単2つの整数と操作コードを受け取り、操作を数値に順番に2回適用して、最終結果を返す関数 apply_twice を記述してください。
関数は、使用する操作を決定する操作コードを受け取ります。解答内で操作関数を定義し、関数ポインタを受け取るヘルパー関数 compute に渡す必要があります。
注: 必要なのは関数のみです。テストでは apply_twice を直接呼び出して戻り値を確認するため、入力の読み取りや何かの出力は行わないでください。
必須構造:
- 2つの
intパラメータを受け取りintを返す関数ポインタのために、Operationという名前のtypedefを定義する - 2つの操作関数を定義する:
add(a + b を返す)とmultiply(a * b を返す) - 2つの整数と
Operation関数ポインタを受け取り、操作を呼び出した結果を返すcompute関数を定義する apply_twice内でコードに基づいて適切な操作を選択し、computeを2回使用する。最初は元の数値に対して、次は結果と2番目の数値に対して再度使用する
ロジック:
op_codeに基づいて操作関数を選択する(1 = add、2 = multiply)compute(a, b, operation)を呼び出して中間結果を取得するcompute(intermediate, b, operation)を呼び出して最終結果を取得する- 最終結果を返す
パラメータ:
a(int): 1番目の数値b(int): 2番目の数値op_code(int): 操作コード(add の場合は 1、multiply の場合は 2)
戻り値: 操作を順番に2回適用した後の結果(int)
例: a = 5、b = 3、op_code = 1(add)の場合:
- 1回目の compute: 5 + 3 = 8
- 2回目の compute: 8 + 3 = 11
- 戻り値: 11
a = 2、b = 4、op_code = 2(multiply)の場合:
- 1回目の compute: 2 × 4 = 8
- 2回目の compute: 8 × 4 = 32
- 戻り値: 32
自分で試してみよう
int apply_twice(int a, int b, int op_code) {
// ここにコードを書いてください
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
自分で練習してみよう: Cオンラインコンパイラ