小白学习大型C++源码项目系列之状态机和图灵机

状态机

什么是状态机?

以操作系统中的任务调度为例来说明什么是状态机。在操作系统的任务调度中经常见到状态机,其作用是根据任务的状态和当前资源条件来改变任务的状态。任务的状态和资源的条件就构成了一个状态机,
在这里插入图片描述

如何描述有限状态机

状态(State)指的是对象在其生命周期中的一种状况,处于某个特定状态中的对象必然会满足某些条件、执行某些动作或者是等待某些事件。

事件(Event)指的是在时间和空间上占有一定位置,并且对状态机来讲是有意义的那些事情。事件通常会引起状态的变迁,促使状态机从一种状态切换到另一种状态。

转换(Transition)指的是两个状态之间的一种关系,表明对象将在第一个状态中执行一定的动作,并将在某个事件发生同时某个特定条件满足时进入第二个状态。

动作(Action)指的是状态机中可以执行的那些原子操作,所谓原子操作指的是它们在运行的过程中不能被其他消息所中断,必须一直执行下去。

代码实践状态机

基于switch(状态)的实现,在实现有限状态机时,使用switch语句是最简单也是最直接的一种方式,其基本思路是为状态机中的每一种状态都设置一个case分支,专门用于对该状态进行控制。下面的代码示范了如何运用switch语句
switch 是另外一种选择结构的语句,用来代替简单的、拥有多个分枝的 if else 语句

基本格式如下: 
 switch(表达式)
 {
    case 整型数值1: 语句 1; break;
    case 整型数值2: 语句 2; break;
    ......
    case 整型数值n: 语句 n; break;
    default: 语句 n+1;
}

它的执行过程是:

  1. 首先计算“表达式”的值,假设为 x。
  2. 从第一个 case 开始,比较“整型数值1”和 x,如果它们相等,就执行冒号后面的所有语句,也就是从“语句1”一直执行到“语句n+1”,而不管后面的 case 是否匹配成功。
  3. 如果“整型数值1”和 x 不相等,就跳过冒号后面的“语句1”,继续比较第二个 case、第三个 case……一旦发现和某个整型数值相等了,就会执行后面所有的语句。假设 x 和“整型数值5”相等,那么就会从“语句5”一直执行到“语句n+1”。
  4. 如果直到最后一个“整型数值n”都没有找到相等的值,那么就执行 default 后的“语句 n+1”。

注意:

break 是一个关键字,专门用于跳出 switch 语句。所谓“跳出”,是指一旦遇到 break,就不再执行 switch 中的任何语句,包括当前分支中的语句和其他分支中的语句;也就是说,整个 switch 执行结束了,接着会执行整个 switch 后面的代码。

由于 default 是最后一个分支,匹配后不会再执行其他分支,所以也可以不添加break;语句。
default 不是必须的。当没有 default 时,如果所有 case 都匹配失败,那么就什么都不执行。

case 后面必须是一个整数,或者是结果为整数的表达式,但不能包含任何变量。
所以case可以和枚举结合使用,关于枚举的用法可以看这篇文章:小白学习大型C++源码项目系列之枚举类(enum class或是enum struct)

#include <iostream>
using namespace std;
void open()
{
    cout << "open !";
}
void close()
{
    cout << "close !";
}
int main(){
    char state;
    printf("Input state :");
    cin >> state;
    switch(state)
    {
        // 处理状态Opened的分支
        case 'o':
            // 执行动作Open
            open();
            break;

        // 处理状态Closed的分支
        case 'c':
            // 执行动作Close
            close();
            break;

        default:
            cout << "state is error !\n";

    }
    return 0;
}
// Input state :o
// open !

图灵机

什么是图灵机

图灵机是数学模型只要图灵机可以被实现,就可以用来解决任何可计算问题。

图灵机的结构

  • 一条无限长的纸带(tape),纸带被分成一个个相邻的格子(square),每个格子都可以写上至多一个字符(symbol)。
  • 一个字符表(alphabet),即字符的集合,它包含纸带上可能出现的所有字符。其中包含一个特殊的空白字符(blank),意思是此格子没有任何字符。
  • 一个读写头(head),可理解为指向其中一个格子的指针。它可以读取/擦除/写入当前格子的内容,此外也可以每次向左/右移动一个格子。
  • 一个状态寄存器(state register),它追踪着每一步运算过程中,整个机器所处的状态(运行/终止)。当这个状态从运行变为终止,则运算结束,机器停机并交回控制权。如果你了解有限状态机,它便对应着有限状态机里的状态。、
  • 一个有限的指令集(instructions table),它记录着读写头在特定情况下应该执行的行为。可以想象读写头随身有一本操作指南,里面记录着很多条类似于“当你身处编号53的格子并看到其内容为0时,擦除,改写为1,并向右移一格。此外,令下一状态为运行。”这样的命令。其实某种意义上,这个指令集就对应着程序员所写下的程序了。

为便于理解打一个比方。算盘虽然不是图灵机(因为它没有无限长的纸带,即无限的存储空间),但它的行为与图灵机一致。每一串算珠都是纸带上的一格,一串算珠上展示的数字便记录着当前格中的字符(可以是空白,可以是 12345 )。人类的手即是读写头,可以更改每串算珠的状态。算盘的运行遵循人脑中的算法,当算法结束,算盘停机。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章