小白學習大型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 )。人類的手即是讀寫頭,可以更改每串算珠的狀態。算盤的運行遵循人腦中的算法,當算法結束,算盤停機。

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