関数ポインタの typedef
CoddyのCジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 35/61。
ご覧のとおり、関数ポインターの宣言は読みにくいことがあります。同じ関数ポインター型を複数の場所で使用する必要がある場合、構文が繰り返しになり、エラーが発生しやすくなります。そこで役立つのが typedef です。
typedefキーワードを使うと、関数ポインターを含む任意の型のエイリアスを作成できます。毎回完全な宣言を書く代わりに、型を一度定義し、コード全体でそのエイリアスを使用します。
関数ポインタ宣言を typedef に変換する方法は次のとおりです:
// typedefなし(messy):
int (*operation)(int, int);
// typedefあり(clean):
typedef int (*Operation)(int, int);
Operation op; // ずっときれい!構文は通常の関数ポインタ宣言に似ていますが、先頭に typedef がある点が異なります。ここで選択した名前(ここでは Operation)は、「2つの int を受け取り、int を返す function へのポインタ」を表す新しい型になります。
これで、この型をどこでも使用できます。
typedef int (*Operation)(int, int);
int add(int a, int b) { return a + b; }
int multiply(int a, int b) { return a * b; }
int main() {
Operation op1 = add;
Operation op2 = multiply;
printf("%d\n", op1(3, 4)); // 出力: 7
printf("%d\n", op2(3, 4)); // 出力: 12
return 0;
}このアプローチは、functionポインタをparametersとして渡したり、構造体に格納したりする場合に特に有用です。これは、ポリモーフィズムに向けて進む中で頻繁に遭遇する状況です。
チャレンジ
簡単typedefを使って、comparison function pointer typeのcleanなaliasを作る練習をしましょう。2つの整数をcomparisonするfunctionを表すtypeを定義し、それを使って変数を宣言し、異なるcomparison functionsを呼び出します。
次のプログラムを書いてください。
- 次の性質を持つfunction pointer typeに対して、
Comparatorという名前のtypedefを作成します。- 2つの
intparametersを受け取る intを返す(negativeはfirstが小さい場合、zeroは等しい場合、positiveはfirstが大きい場合)
- 2つの
- 2つのcomparison functionsを定義します。
ascending:ascending orderを示す値(first - second)を返すdescending:descending orderを示す値(second - first)を返す
mainで、Comparator変数を宣言します(raw function pointer syntaxではなく、作成したtypedefを使用します)- 3つのinputを読み取ります:2つの整数とorder code(ascendingの場合は1、descendingの場合は2)
- order codeに基づいて、appropriateなfunctionを
Comparator変数にAssignします - 2つのnumberを使ってcomparatorをCallし、resultを出力した後、どの値がfirstになるべきかを示すメッセージを出力します
3つのinputを受け取ります:first number、second number、およびorder code(1または2)です。
Outputにはcomparison resultを表示し、その後、resultの符号に基づいてどのnumberがfirstになるかを示します。
Result: -5
First: 3入力が3、8、1(ascending order)のこの例では、comparisonは3 - 8 = -5となります(negativeはascending orderでfirst numberがfirstになることを意味します)。そのため、First: 3とPrintします。
「First」行について:
- resultがnegativeまたはzeroの場合、first input numberをPrintします
- resultがpositiveの場合、second input numberをPrintします
ここでのkey practiceは、full function pointer syntaxを書き出すのではなく、Comparator typedefを使ってvariableをcleanにDeclareすることです。
自分で試してみよう
#include <stdio.h>
// TODO: 関数ポインタ型のための 'Comparator' という typedef を作成する
// 2つの int パラメータを取り、int を返す
// TODO: 'ascending' 比較関数を定義する
// (first - second) を返すべき
// TODO: 'descending' 比較関数を定義する
// (second - first) を返すべき
int main() {
// 入力を読み取る
int num1, num2, orderCode;
scanf("%d", &num1);
scanf("%d", &num2);
scanf("%d", &orderCode);
// TODO: typedef を使って Comparator 変数を宣言する
// TODO: orderCode に基づいて適切な関数を割り当てる
// (1 は ascending、2 は descending)
// TODO: コンパレータを呼び出して結果を格納する
int result;
// 結果を出力する
printf("Result: %d\n", result);
// TODO: 結果に基づいてどちらの数字が先に来るかを出力する
// 結果が負またはゼロの場合、最初の数字を出力する
// 結果が正の場合、2番目の数字を出力する
printf("First: %d\n", /* ここにロジックを書く */ 0);
return 0;
}このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
自分で練習してみよう: Cオンラインコンパイラ