Menu
CoddyTech

関数ポインタの 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として渡したり、構造体に格納したりする場合に特に有用です。これは、ポリモーフィズムに向けて進む中で頻繁に遭遇する状況です。

challenge icon

チャレンジ

簡単

typedefを使って、comparison function pointer typeのcleanなaliasを作る練習をしましょう。2つの整数をcomparisonするfunctionを表すtypeを定義し、それを使って変数を宣言し、異なるcomparison functionsを呼び出します。

次のプログラムを書いてください。

  1. 次の性質を持つfunction pointer typeに対して、Comparatorという名前のtypedefを作成します。
    • 2つのint parametersを受け取る
    • intを返す(negativeはfirstが小さい場合、zeroは等しい場合、positiveはfirstが大きい場合)
  2. 2つのcomparison functionsを定義します。
    • ascending:ascending orderを示す値(first - second)を返す
    • descending:descending orderを示す値(second - first)を返す
  3. mainで、Comparator変数を宣言します(raw function pointer syntaxではなく、作成したtypedefを使用します)
  4. 3つのinputを読み取ります:2つの整数とorder code(ascendingの場合は1、descendingの場合は2)
  5. order codeに基づいて、appropriateなfunctionをComparator変数にAssignします
  6. 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;
}
quiz icon腕試し

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

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

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