1

Cで有限状態マシンを実装しようとしていますが、非常に高速である必要があります。そこで、関数ポインタを「状態」として使用することにしました。

void *state1(void){ /* function body here */ }
void *state2(void){ /* ... */ }
void *state3(void){ /* ... */ }

次に、メインのFSMループは非常に単純になります。

void *(*fp)(void);
fp = state1;

while(fp)
    fp = fp();

質問があります:

1)関数の戻り型でvoidポインタを使用しないようにすることは可能ですか?理想的には、ステート関数は、FSMでこのタイプの関数のみが使用されるように、typedefされたタイプを持つ必要があります。

2)CでFSMを実装する従来のアプローチでは、状態に列挙型とスイッチベースのディスパッチャーループを使用するため、関数ポインターベースの実装と比較すると、1つの間接レベルがあります。
しかし、よくわかりません。命令キャッシュや分岐予測に問題があるのでしょうか。言い換えれば、私のソリューションを上回ることができる実装が存在する可能性がありますか?

ありがとう。

4

5 に答える 5

3

Cでこのような再帰型定義を作成するには、structtypedefを「前方宣言」できないため、行のどこかを使用する必要があります。たとえば、関数ポインタをstruct:内でラップできます。

struct state {
    struct state (*func)(void);
};

次に、ループ内で:

struct state state = { state1 };

while (state.func) {
    state = state.func();
}
于 2012-06-25T04:03:44.777 に答える
3

ここであなたはあなたの質問に対する答えを見つけるかもしれません:http ://code.google.com/p/fwprofile/

これは、Cで実装されたステートマシンのオープンソースバージョン(GNU GPLv3)です。この概念と実装は、ミッションクリティカルなアプリケーションでの使用に最適です。産業用アプリケーションでの展開があります。

于 2012-09-12T08:35:35.650 に答える
1

Cでは、独自の型の関数へのポインタを返す関数を宣言することはできません。また、void *Cでは関数ポインタとオブジェクトポインタ間の変換ができないため、使用できません。代わりに、次を使用できます。

typedef void (*generic_func_ptr)(void);
typedef generic_func_ptr (*state_func_ptr)(void);
generic_func_ptr state1(void), state2(void), state3(void);
state_func_ptr fp;

while(fp)
    fp = (state_func_ptr)fp();

醜いですが、動作します。代わりに、switchステートメントの使用を検討します。ステートマシンを実装するのに非常にクリーンです。

于 2012-06-25T04:01:41.027 に答える
0

1)typedef void(*state_fp)(void);

state_fp state1(void) { }

2)依存しますが、関数にコードが組み込まれている小さなループは、関数呼び出しを行うよりも高速です。たとえば、各状態がswitchステートメントに実装されているswitchステートメントですが、caseステートメントが多すぎると、関数呼び出しよりも低くなります。

于 2012-06-25T03:20:18.163 に答える
0

他の人がfsmに無料のフレームワークを使用したい場合は、http: //www.block-net.de/Programmierung/cpp/fsm/fsm.htmlを参照してください。 状態を含むCおよびC++の有限状態マシンフレームワークがあります。 PlantUMLを使用したチャートジェネレータ。

于 2014-10-09T22:07:33.870 に答える