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 中仅使用具有这种类型的函数。

2)在 C 中实现 FSM 的传统方法是使用枚举作为状态和基于开关的调度程序循环,因此与基于函数指针的实现相比,会有一个间接级别。
但我不确定,指令缓存或分支预测是否存在一些问题?换句话说,是否存在可以胜过我的解决方案的实现?

谢谢。

4

5 回答 5

3

要在 C 中创建这样的递归类型定义,您需要在struct某处使用 a ,因为您不能“前向声明”类型定义。例如,您可以将函数指针包装在 a 中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

如果其他人想为 fsm 使用免费框架,请查看http://www.block-net.de/Programmierung/cpp/fsm/fsm.html 有一个 C 和 C++ 有限状态机框架,包括状态带有 PlantUML 的图表生成器。

于 2014-10-09T22:07:33.870 回答
0

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

state_fp state1(void) { }

2) depends, a small loop with the code built into the function will be faster than making function calls. eg, a switch statement where each state is implemented in the switch statement, however, if there is too many case statements, this will degrade below function calls

于 2012-06-25T03:20:18.163 回答