![]() |
1
149
对于大多数状态机,我更喜欢使用表驱动的方法:
当然,这可以扩展到支持多状态机等。也可以适应转换操作:
表驱动方法更易于维护和扩展,并且更易于映射到状态图。 |
![]() |
2
26
你可能已经看到了我对另一个C问题的回答,我提到了FSM!我是这样做的:
定义了以下宏
现在有两种类型的转换:一种进入状态并读取新字符,另一种进入状态而不消耗任何输入。 您还可以通过以下方式自动处理EOF:
在用于实现FSM的其他技术中,转换的结构被埋入控制结构(while、if、switch…)中,并由变量值控制(典型地是a)
我从一篇发表在《计算机语言》杂志上的文章中学到了这项技术,不幸的是,这篇文章已不再出版。 |
![]() |
3
15
我也使用了表格法。然而,也存在开销。为什么要存储第二个指针列表?C中不带()的函数是常量指针。因此,您可以:
此外,我从OP的示例中感觉到,在考虑/设计状态机时,应该进行简化。我不认为转换状态应该用于逻辑。每个状态函数应该能够在不明确了解过去状态的情况下执行其给定的角色。基本上,您设计的是如何从您所处的状态过渡到另一个状态。 最后,不要开始基于“功能”边界的状态机设计,使用子功能。取而代之的是,根据你必须等待事情发生的时间来划分状态,然后才能继续。这将有助于减少在获得结果之前必须运行状态机的次数。这在编写I/O函数或中断处理程序时非常重要。 此外,经典switch语句的一些优点和缺点: 赞成的意见:
欺骗:
请注意两个属性,它们都是赞成和反对的。我认为,这种转变为州与州之间的过度共享提供了机会,州与州之间的相互依赖性可能变得难以管理。然而,对于少数几个状态,它可能是可读性和可维护性最好的。 |
![]() |
4
12
在里面 Martin Fowler's UML Distilled ,他在第10章状态机图中指出(无双关语):
让我们使用一个手机显示状态的简化示例:
嵌套开关
状态模式下面是我的示例中GoF状态模式的一个实现:
状态表以福勒为灵感,以下是我的示例: Source State Target State Event Guard Action -------------------------------------------------------------------------------------- ScreenOff ScreenOff pressButton powerLow displayLowPowerMessage ScreenOff ScreenOn pressButton !powerLow ScreenOn ScreenOff pressButton ScreenOff ScreenCharging plugPower ScreenOn ScreenCharging plugPower ScreenCharging ScreenOff unplugPower 比较嵌套开关将所有逻辑保持在一个位置,但当存在大量状态和转换时,代码可能很难读取。它可能比其他方法(无多态性或解释)更安全、更容易验证。 状态模式实现可能将逻辑扩展到几个单独的类上,这可能会使理解它作为一个整体成为一个问题。另一方面,小类很容易单独理解。如果您通过添加或删除转换来更改行为,那么设计尤其脆弱,因为它们是层次结构中的方法,并且可能会对代码进行大量更改。如果你遵循小型接口的设计原则,你会发现这种模式并不是很好。然而,如果状态机是稳定的,那么就不需要这样的更改。 状态表方法需要为内容编写某种类型的解释器(如果您使用的语言中有反射,这可能会更容易),这可能需要大量的前期工作。正如Fowler所指出的,如果表与代码分开,则无需重新编译即可修改软件的行为。然而,这有一些安全问题;软件的运行基于外部文件的内容。 编辑(不适用于C语言)first-class functions . 这个 Stateless library 存在,该博客显示了一个简单的代码示例。A. Java implementation (pre Java8) Python example on GitHub |
![]() |
5
10
对于简单的状态机,只需使用switch语句和状态的枚举类型。根据输入在switch语句中执行转换。在实际的程序中,您显然会更改“if(input)”以检查过渡点。希望这有帮助。
|
![]() |
6
9
logic grid 随着状态机变得越来越大,哪个更易于维护 |
![]() |
7
4
对于简单的情况,可以使用切换样式方法。我发现过去行之有效的方法是处理过渡:
我对boost库一无所知,但这种方法非常简单,不需要任何外部依赖,而且易于实现。 |
![]() |
8
4
switch()是C中实现状态机的一种强大且标准的方法,但是如果有大量状态,它会降低可维护性。另一种常用方法是使用函数指针存储下一个状态。这个简单的例子实现了一个设置/复位触发器:
|
![]() |
9
4
我在由Jonathan Valvano和Ramesh Yerraballi撰写的edx.org课程《嵌入式系统-塑造世界UTAustinX-UT.6.02x》第10章中发现了摩尔FSM的一个非常巧妙的C实现。。。。
|
![]() |
10
2
你可能想调查一下 FSM生成器软件。从状态描述语言和/或(Windows)状态图编辑器,您可以生成C、C++、java和许多其他代码…再加上漂亮的文档和图表。 源代码和二进制文件 iMatix |
![]() |
11
2
This article 是状态模式的好方法(虽然它是C++,而不是C)。 如果你能把手放在书上“ Head First Design Patterns |
![]() |
12
2
我最喜欢的模式之一是state设计模式。对同一组给定的输入做出不同的响应或行为。
stateCText.h:
stateCText.c:
stateholders.h:
stateholders.c:
|
![]() |
13
1
根据我的经验,使用“switch”语句是处理多种可能状态的标准方法。尽管我很惊讶您正在将转换值传递给每状态处理。我认为状态机的全部意义在于每个状态执行一个动作。然后,下一个操作/输入确定要转换到哪个新状态。所以我希望每个状态处理函数立即执行为进入状态而确定的任何操作,然后再决定是否需要转换到另一个状态。 |
![]() |
14
1
有一本书名为 Practical Statecharts in C/C++ . 然而,事实并非如此 对于我们所需要的东西来说太重了。 |
![]() |
15
1
对于支持哪种编译器
|
![]() |
16
1
您可以在c中使用最简单的UML状态机框架。 https://github.com/kiishor/UML-State-Machine-in-C
状态机由
状态由指向的指针表示
若框架是为有限状态机配置的,那个么
该框架提供了一个API
有关如何实现分层状态机的更多详细信息,请参阅GitHub存储库。
代码示例
|
![]() |
17
0
在C++中,考虑 State pattern . |
![]() |
18
0
您的问题类似于“是否存在典型的数据库实现模式”? 答案取决于你想要实现什么?如果您想要实现更大的确定性状态机,您可以使用模型和状态机生成器。 示例可在www.StateSoft.org-SM Gallery上查看。贾努斯·多布罗沃尔斯基 |
![]() |
19
0
我也更喜欢表驱动的方法。我用过
下面是这种方法的演示。
|
![]() |
20
-1
|
![]() |
Community wiki · C中有哪些耗时的操作? 1 年前 |
![]() |
Community wiki · 将所有处理器电源都投入到任务中 1 年前 |
![]() |
Community wiki · C++为C添加了什么?[已关闭] 1 年前 |
![]() |
Community wiki · 打印1到1000,不带循环或条件 1 年前 |