我有以下代码来定义我的FSM状态:
enum states
{
START, // Send request to remote IP or wait for a request (WAIT_CONN_REQ)
WAIT_RESP, // Chat request sent to remote IP. Waiting for a response from the target machine
SEND_CONN_RESP, // Chat request received from remote IP. ACCEPT or REJECT
ACCEPTED // Both parties agreed to exchange datagrams. Begin application data (MESSAGES) exchange
};
typedef enum states states;
states state;
我的思维过程是这样的:我的聊天程序将具有上述四种状态。整齐地做这件事最好的方法是什么?当然,使用switch语句。那我该怎么办呢?像这样:(代码被简化并替换为printf
函数“
int main(int argc, char *argv[])
{
state = START;
switch (state)
{
case START:
printf("Simple Chat Client - START state\n");
if (argv[1] != NULL)
{
SEND_CONN_REQ();
} else {
WAIT_CONN_REQ();
}
break;
case WAIT_RESP:
printf("WAIT_RESP STATE!");
break;
case SEND_CONN_RESP:
printf("SEND_CONN_RESP state!");
break;
case ACCEPTED:
printf("ACCEPTED state!");
break;
}
}
但这不符合我的要求。我希望它在满足条件时跳转到另一个案例。像这样:
if (argv[1] != NULL)
{
SEND_CONN_REQ();
goto case WAIT_RESP;
} else {
WAIT_CONN_REQ();
}
break;
case WAIT_RESP:
printf("WAIT_RESP STATE!");
break;
我的逻辑告诉我,这样做的方法是更改state
变量,假设将使用新变量再次执行整个switch
。但是,我必须使用break
并退出switch
,或者不使用它,让程序执行下一个case
。
所以我查看了其他选项,例如do
语句和continue
。但在我看来,使用case
似乎是使用FSM的方式。
如果能够正确地做到这一点,我将不胜感激。 switch
声明是最好的方式吗?
答案 0 :(得分:2)
像这样编码状态机的常用方法是使用循环和开关:
state = START;
while (state != STOP)
{
switch (state)
{
case START:
printf("Simple Chat Client - START state\n");
if (argv[1] != NULL)
{
SEND_CONN_REQ();
} else {
WAIT_CONN_REQ();
}
break;
case WAIT_RESP:
printf("WAIT_RESP STATE!");
break;
case SEND_CONN_RESP:
printf("SEND_CONN_RESP state!");
break;
case ACCEPTED:
printf("ACCEPTED state!");
break;
}
}
每个操作都可以选择设置新状态,以便下一次迭代将执行相应的操作。如果要及时查看输出,请不要忘记在printf()
语句的末尾输出换行符。在Windows上可能无关紧要;它在其他平台上。
答案 1 :(得分:0)
如果您始终只想执行下面的状态,则可以删除break
语句。我会在/* fall through */
这样的地方发表评论,这样很明显,对于跟随的人以及你未来遗忘的自我而言,它是故意遗漏的。我个人不喜欢这种方法。
为什么不更改state
变量,然后只执行位于switch语句正上方的goto
?像这样可能:
switchStart:
switch (state)
{
case START:
printf("Simple Chat Client - START state\n");
if (argv[1] != NULL)
{
SEND_CONN_REQ();
state = STATE_HERE; // change your state
goto switchStart; // jump to the top of the switch
} else {
WAIT_CONN_REQ();
}
break;
case WAIT_RESP:
printf("WAIT_RESP STATE!");
break;
case SEND_CONN_RESP:
printf("SEND_CONN_RESP state!");
break;
case ACCEPTED:
printf("ACCEPTED state!");
break;
}