这里的答案看起来很复杂(但很准确)。所以这是我的想法。
首先,我喜欢 dmckee 对 FSM 的(操作性)定义以及它们如何应用于编程。
一个有限状态机由一个
有限数量的离散状态(我
知道迂腐,但仍然),这可以
一般用整数表示
价值观。在 c 或 c++ 中使用
枚举很常见。
机器响应有限
输入的数量通常可以是
用另一个整数表示
值变量。在更复杂的
案例你可以使用一个结构
表示输入状态。
内部状态的每个组合和
外部输入会导致机器
到:
- 可能会转换到另一个状态
- 可能会产生一些输出
所以你有一个程序。它有状态,并且它们的数量是有限的。 (“灯泡亮”或“灯泡暗”或“灯泡熄灭。”3 种状态。有限。)您的程序一次只能处于一种状态。
因此,假设您希望程序更改状态。通常,您会希望发生某些事情来触发状态更改。在这个例子中,我们如何通过用户输入来确定状态——比如按键。
您可能需要这样的逻辑。当用户按键时:
- 如果灯泡“关闭”,则使灯泡“变暗”。
- 如果灯泡“暗”,则使灯泡“亮”。
- 如果灯泡“亮”,则将灯泡“关闭”。
显然,您可能不是“更改灯泡”,而是“更改文本颜色”或您的程序需要做的任何事情。在开始之前,您需要定义您的状态。
所以看看一些伪 C 代码:
/* We have 3 states. We can use constants to represent those states */
#define BULB_OFF 0
#define BULB_DIM 1
#define BULB_BRIGHT 2
/* And now we set the default state */
int currentState = BULB_OFF;
/* now we want to wait for the user's input. While we're waiting, we are "idle" */
while(1) {
waitForUserKeystroke(); /* Waiting for something to happen... */
/* Okay, the user has pressed a key. Now for our state machine */
switch(currentState) {
case BULB_OFF:
currentState = BULB_DIM;
break;
case BULB_DIM:
currentState = BULB_BRIGHT;
doCoolBulbStuff();
break;
case BULB_BRIGHT:
currentState = BULB_OFF;
break;
}
}
而且,瞧。一个改变状态的简单程序。
此代码仅执行switch 语句的一小部分 - 取决于当前 状态。然后它更新该状态。这就是 FSM 的工作原理。
现在你可以做一些事情:
显然,这个程序只是改变了currentState 变量。您会希望您的代码在状态更改时做一些更有趣的事情。 doCoolBulbStuff() 函数可能,我不知道,实际上是在屏幕上放一张灯泡的图片。什么的。
-
此代码仅查找按键。但是您的 FSM(以及您的 switch 语句)可以根据用户输入的内容来选择状态(例如,“O”的意思是“关闭”,而不仅仅是进入序列中的下一个。)
李>
您的部分问题要求数据结构。
有人建议使用enum 来跟踪状态。这是我在示例中使用的#defines 的一个很好的替代方案。人们也一直在建议使用数组——这些数组会跟踪状态之间的转换。这也是一个很好用的结构。
鉴于上述情况,您可以使用任何类型的结构(类似树的东西、数组、任何东西)来跟踪各个状态并定义在每个状态下要做什么(因此有一些建议使用“函数指针” - 具有指向函数指针的状态映射,指示在该状态下要做什么。)
希望有帮助!