【C言語】関数ポインタのテーブルの使い方 – 状態遷移表をそのまま実装に落とし込む。if, switch不要で。

Cの関数ポインタテーブルと状態遷移表

組み込みではよく設計フェーズで状態遷移表を作って、それを元に実装したり、試験したりする。状態遷移表はC言語の関数ポインタのテーブルと相性が良く、表をそのまま二次元配列に格納すると設計をそのまま実装として表す事が出来る。

関数ポインタのテーブルを使用するとif文・switch文を使わずに状態遷移表が書けるので、場合によっては可読性が向上するし、インデックスでテーブルの各行の関数にアクセスできれば実行速度的にも有利だ。

ただ関数ポインタを用いたテーブルは、入門的なC言語の書き方と異なるので、読むにも書くにも頭の整理が必要になる。頭の整理を兼ねて、状態遷移表をそのままC言語で表す例を書いてみることにした。ここでは、ifもswitchも(条件分岐として使用できるforもwhileも)使用しない縛りの中で、状態遷移の条件分岐を書いてみることにした。

状態遷移の仕様を仮定する

状態遷移表は、状態とイベントの2次元のマトリックスで表現する。例として、状態には腹の減り具合を、イベントには母親から「何々を食え・飲め」と言われたり、言われた通りに完食したりといった事を想定する。

ここで、以下の仕様と仮定する。

  • 空腹であればラーメンも食えるしタピオカも飲めるが、胃薬は飲めない
  • 食事中であれば食事完了まで何も飲み食い出来ない。
  • 食事完了したら満腹になる。
  • 満腹になったらラーメンは食えないが、デザートのタピオカは飲める。
  • 満腹時に胃薬を飲むと空腹に戻る。

これを状態遷移表で表すと以下のようになる。

状態\イベントラーメンを食えタピオカを飲め胃薬を飲め食事完了
空腹食事中へ食事中へ拒否
食事中拒否拒否拒否満腹へ
満腹拒否食事中へ空腹へ

本当に満腹の時にタピオカが飲めるのか、そもそもタピオカはデザートなのか、胃薬を飲んだら空腹になるのかというツッコミは絶えないと思うが、仕様は絶対なのでそのとおりに実装することにする(おいっ)

また言うまでも無く、この仕様にはタピオカは空腹を挟まず無限に飲めるという明らかなバグが存在するが、やはり仕様は絶対なので気にせず、仕様通りに実装することにする(おいっ)

state_machine_sample.c



		


実行結果は以下



		


コメント

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