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文を減らすことができ、処理の追加などでもディシジョンテーブル(決定表)を修正するだけで済むようになります。
これで随分メンテナンスがしやすいソースになりました。
