3

関数ポインタの配列を使用する利点は何ですか?Cの関数プロトタイプの数を減らす以外に。

4

4 に答える 4

3

多くの人が指摘しているように、関数ポインタを使用して、Cでオブジェクト指向プログラミングをエミュレートできます。

たとえば、適切なメソッド(別名仮想メソッド)の選択は、単純なインデックス作成を使用して行うことができます。

#include <stdio.h>
#include <stdlib.h>

typedef void (*menu_function_t)();

void menu_error()
{
    printf("Invalid menu choice\n");
}

void menu_exit()
{
    exit(0);
}

void menu_function1()
{
    printf("You have selected 1\n");
}

void menu_function2()
{
    printf("You have selected 2\n");
}

menu_function_t menu_ptr[] = {
    menu_function1, menu_function2,  menu_exit, menu_error
};

int menu_num = sizeof(menu_ptr) / sizeof(menu_ptr[0]);

int validate_choice(int a)
{
    if(a < 0 || a > menu_num - 2) { return 3; }

    return a;
}

int main()
{
    int choice = 0;

    while(1)
    {
        printf("Choose item: \n");
        printf("0) Function 1\n");
        printf("1) Function 2\n");
        printf("2) Exit\n");
        scanf("%d", &choice);

        menu_ptr[ validate_choice(choice) ]();
    }

    return 0;
}
于 2012-09-23T21:32:59.237 に答える
2

関数ポインタを保持する配列(または他のデータ構造)にはさまざまなユースケースがあります。一般に、このタイプのメカニズムにより、プログラムは実行時の基準に基づいていくつかの異なる関数の1つを動的に呼び出すことができます。

たとえば、関数ポインタの配列を使用して、オブジェクト指向言語のインターフェイスに似たものを実装できます。配列は、そのインターフェイスの各実装へのポインタを保持します。配列インデックスは、いくつかの基準に基づいて、目的の実装を選択するために使用されます。

于 2012-09-23T21:23:32.270 に答える
2

数値を操作に関連付けたい場合は、関数ポインターの配列を使用できますが、実際にはマップと呼ばれます。switchそれは大きな声明を持つことを節約するでしょう。

array[CMD_OPEN] = OpenFunction;
array[CMD_CLOSE] = CloseFunction;

void HandleCommand(int aCommand)
{
    array[aCommand]();
}
于 2012-09-23T21:31:13.293 に答える
1

1つの例(多く存在します)は、一連の変数「メソッド」を実装する場合です。

typedef struct tag_IMAGEFORMAT
{
        struct tag_IMAGEFORMAT *next;
        const char      *name;
        IMAGEDETECTOR   *detect_routine;
        int             (*open_routine)         (DISKIMAGE *img, diskimgflags_t flags);
        size_t          (*read_routine)         (DISKIMAGE *img);
        int             (*close_routine)        (DISKIMAGE *img);
} IMAGEFORMAT;

Cでのオブジェクト指向プログラミング。次に、たとえばを呼び出します。object->open_routine(..)この例では、実行時に実装を動的に変更できます(この例では、画像形式によって異なります)。

この例では、いくつかの画像形式が共通のAPIを共有しています。さまざまな「検出器」が次々に実行され、最初に一致したものがそのポインタを「一般的な画像」オブジェクトにコピーします。その後、実装の詳細(JPG、GIF、PNGなど)を気にせずに画像を操作できます。

同様に、関数のいくつかの異なるバリエーション(たとえば、画像フィルター)を実装する必要がある場合は、すべてのポインターを配列に保持し、配列へのインデックスを介して適切なポインターを選択できます。

于 2012-09-23T21:24:45.503 に答える