C言語の関数ポインタでディシジョンテーブル(決定表)を作る

C言語には関数のアドレスを管理するための変数「関数ポインタ」があります。

今回はC言語の関数ポインターでディシジョンテーブル(決定表)を作って、IF文を減らしてソースを簡易にしてみます。

スポンサーリンク

C言語の関数ポインタ

C言語には関数のアドレスを管理する「関数ポインタ」という変数を作ることができます。

関数ポインタの宣言は
   関数の戻り値型 ( 変数名 )( 引数・・・);
で宣言します。

実際に書くと

int ( *po )( int, char, long ) ;

のようになります。

関数ポインタでディシジョンテーブル(決定表)を作る

では実際に関数ポインタでディシジョンテーブル(決定表)を作ってみます。

でもその前に「関数ポインタのディシジョンテーブル(決定表)」を使わずに書くとどうなるかやってみます。

#include <stdio.h>
#include <string.h>

//プロトタイプ宣言
void dog( void ) ;
void cat( void ) ;
void monkey( void ) ;

//メイン関数
int main() {
    char s[ 20 ] ;

    printf( "実行する関数を指定してください dog,cat,monkey >" ) ;
    gets( s ) ;
    if( strcmp( "dog", s ) == 0 ){
        dog();
    } else if( strcmp( "cat", s ) == 0 ){
        cat();
    } else if( strcmp( "monkey", s ) == 0 ){
        monkey();
    } else {
        printf("%sは決定表の中にはありません。\n", s ) ;
    }
    return 0 ;
}

//イヌの鳴き声
void dog() {
    printf("bow wow\n");
}

//ネコの鳴き声
void cat() {
    printf("meow\n");
}

//サルの鳴き声
void monkey() {
    printf("screech\n");
}

となります。

これを「関数ポインターのディシジョンテーブル(決定表)」を使うと

#include <stdio.h>
#include <string.h>

//プロトタイプ宣言
void dog( void ) ;
void cat( void ) ;
void monkey( void ) ;

//決定表(ディシジョンテーブル)定義構造体
typedef struct{
    char label[ 20 ] ;
    void ( *po )() ;     /*関数ポインタ宣言*/
} DECISION_TABLE ;

//メイン関数
int main() {
    char s[ 20 ] ;
    DECISION_TABLE dt[ 3 ] ={
                             { "dog",    dog }
                            ,{ "cat",    cat }
                            ,{ "monkey", monkey }
    } ;

    printf( "実行する関数を指定してください dog,cat,monkey >" ) ;
    gets( s ) ;
    for( int i = 0 ; i < sizeof( dt ) / sizeof( DECISION_TABLE ) ; i++ ){
        if( strcmp( dt[ i ].label, s ) == 0 ){
            dt[ i ].po();
            return 0;
        }
    }
    printf("%sは決定表の中にはありません。\n", s ) ;
    return 0 ;
}

//イヌの鳴き声
void dog() {
    printf("bow wow\n");
}

//ネコの鳴き声
void cat() {
    printf("meow\n");
}

//サルの鳴き声
void monkey() {
    printf("screech\n");
}

となり「if文」が随分と少なくなりました。

また、動物の鳴き声関数が増えててもディシジョンテーブル(決定表)を追加するだけでif文を追加する必要はなく、メインループの変更はなくなりました。

まとめ

C言語の関数ポインタを使ってディシジョンテーブル(決定表)を作って処理を分岐させると、IF文を減らすことができ、処理の追加などでもディシジョンテーブル(決定表)を修正するだけで済むようになります。

これで随分メンテナンスがしやすいソースになりました。

タイトルとURLをコピーしました