第11回 コーディング(1)(6月27日)

■ オプションの解析と処理の起動

プログラミングの参考資料を示す。

ソーティングの基準には、得点順、誕生日順、身長順など様々な種類が考えられる。コマンドラインで実行する際、オプションのスイッチを使うことで、これらの機能を選択したい。

例えば、「> ./prog SORT_BY_NAME」というオプションのときは、名前の ABC 順でソートし、「> ./prog SORT_BY_SCORE」というオプションのときは、得点順でソートするという実行方法である。

ところで、第5回の演習で、qsort を用いたソーティングを練習した。何を基準としてソートするのかは、比較関数の指定によりコントロールしていた。そのこと応用すると、オプション解析時に SORT_BY_NAME という指定であれば、たとえば、cmp_function1 という関数が比較関数として指定すればよく、SORT_BY_SCORE という指定であれば cmp_function2 という関数が比較関数として指定すれば良い。

具体的に、プログラムの骨組みを示す。
// 比較関数についての関数ポインタの型宣言 ⇒  CmpFunc 型が使用可能になる
typedef int (* CmpFunc)(NameCard **, NameCard **);

// 総合得点による比較
int cmp_by_total_point(NameCard **nc1, NameCard **nc2)
{
  return nc_get_gp_total(*nc2) - nc_get_gp_total(*nc1);
}

// ドライバー番号による比較
int cmp_by_driver_number(NameCard **nc1, NameCard **nc2)
{
  return nc_get_driver_number(*nc1) - nc_get_driver_number(*nc2);
}

// オプション解析
void parse_options(char **argv, CmpFunc *ans)
{
  if( strcmp( argv[1], "SORT_BY_SCORE" ) == 0 )
    *ans = cmp_by_total_point;   // 関数名は、関数へのポインタを表す
  else if( strcmp( argv[1], "SORT_BY_NUMBER" ) == 0 )
    *ans = cmp_by_driver_number; // 関数名は、関数へのポインタを表す
  else
    *ans = NULL;
}

// メイン
int main(int argc, char **argv)
{
  CmpFunc cmp_func;
  NameCard **ncarray;

  parse_options( argv, &cmp_func );
  ncarray = make_name_card( - - - );
  qsort( ncarray, number_of_cards( ncarray ), sizeof(NameCard *), cmp_func );
  output_name_card( ncarray, - - - );
}

Linked List を使う場合、データ入力時に、データを比較する。その比較のための関数としても、上記の方法は利用できる。


(c) Masato TOKUHISA (2008, June 27th.)