Cパズルプログラミング-再帰編 > 基本的過ぎること > 四則演算 > 整理


[Prev] [Next] [Up] [Contents][フレーム表示] [フレーム解除

整理 応援する 

以上で一応再帰的に動くプログラムにはなったのだが、 実は色々問題があるので、それらについてちょっと指摘しておこう。

gettoken() を呼ぶタイミングが、 factor()、term()、expr()の3つでまちまちになっている。 expr() はその中で最初に gettoken() を呼んでいるのだが、 factor()、term() の2つは、呼ばれた時点では、 gettoken() は既に呼ばれていて、 配列 token にトークンが設定済みとなっている。

3つの関数でこんなに違うのは良くない。 いずれの関数でも、 「gettoken() は既に呼ばれていて、配列 token にトークンが設定済み」 となるようにしよう。 すると、1つ問題が出て来る。 それは、最初に expr() が呼ばれる時である。 もし、gettoken() が呼ばれていると仮定すると、 main() の中で、トークンを意識しなくてはならなくなる。

ということで、ちょっと細工をしよう。 exprではなく、 expressin( char *str ) なる関数を新設しよう。 そして、main() からは、入力された文字列を expressin() の引数で渡すと、 式を評価した結果の値が戻って来るようにしよう。 こうすると、expressin() を利用する立場からは、 トークンについて何も意識しなくていい。

その代り、トークン関係の初期化などは、expressin()がすることになる。

まあ、そんな感じで書き換えてみたのが、 expr6.c である。

動作は何も変わっていない筈である。

ここでは簡単な再帰の実験ということだったので、 1つのファイルにまとめてしまったが、 ちゃんと作るのだったら、 expressin だけをグローバルな関数として作り、 他の部分は見えなくしてしまうのが良いだろうが、 そのあたりは勝手に工夫して欲しい。

ここで、再帰について、これが階乗や組合せよりも ちょっと複雑になっているのがお分かりだろうか。 階乗や組み合わせは、引数に対しての処理だけであったが、 今回は入力した文字列を解釈しながらトークンを切り出すという作業がこっそり進行しているのである。 要するに、状態が次第に変化しているのである。 この状態変化こそが非常に重要な部分なのである。 こういう部分がまったくない再帰というのは、 定義上は非常に複雑でも、 プログラム的には極めて簡単であり、 定義を書き写すだけで済む。 パズルの場合、再帰と言っても、 色々関数の外側の状態(外界)が再帰の計算が進むと 変わってしまうことが多い。 変わって良い場合もあれば、 必要に応じて戻してやらなければならないこともある。 それらは、そのうち分かるようになるだろう、きっと。

2001年9月3日


[Prev] [Next] [Up] [Contents][フレーム表示] [フレーム解除

Subtitles


このサイトについて|ヘルプ|Q&A|個人情報保護|プライバシーポリシー|利用規約|コメント・トラックバック規約|削除規程|広告掲載
Copyright (c) 2005-2007 Time Intermedia Corporation