控制表

控制表是一個決定控制流程或是主要影響控制流程的表。關於控制表的結構或內容沒有硬性的規定，其特點是其可以影響控制流程的能力。這類表格的設計有時稱為「表格驅動設計」。以有限狀態機為基礎的自動機程式設計有時會用控制表為其實現方式。若控制表有幾個不同的層次，其行為就類似。控制表有時會以的方式表示，其中會有對應的條件表示式及子程式。控制表可以簡化一些類似的程式敘述，而且若是二維的控制表，在閱讀及更新上都比一維特性的程式碼要容易維護，有時控制表甚至可以讓非程式設計師來維護。電腦科學家高德納在1974年提出的論文《Structured Programming with go to Statements》中就提到「多路分支是一種重要的程式設計技術，但常常被一些數量不足的if指令取代」。類似位元組碼，但常會配合控制表的結構中隱含的動作而運作。表格結構.控制表可以是多維的，可以是固定長度或是，而且具有可在不同系統平臺之間使用的可攜性，系統平臺變動時只針對直譯器修改軟體，不會變動隱含在控制表的結構及其內容中的演演算法。控制表的結構可能類似一個multimap的關聯表，會將資料值對映到一個或多個要進行的函式。一維表格.控制表可以是一維表格的形式，這可能也是最簡單的控制表。一維表格的控制表將原始資料轉換為副程式的偏移值、編號或是指標，轉換方式可能是直接以為索引進行查表，或是將原始資料進行簡單的數學處理後再作為表格的索引。查表的過程不會用到線性搜尋或是二分搜尋，可以在常數時間內完成。對於大部份的電腦架構而言，上述處理可以利用二或三個機器語言的指令來達成，不需進行比較或是迴圈處理。此技術一般稱為「Trivial hash function」，若特別用在分支表中，則稱為。若要使用一維表格的控制表，資料的可能範圍需要很小，像ASCII或EBCDIC字元都只有255個可能資料，符合此條件，若資料是用ASCII字元表示，且可以確認其中有些資料不可能出現，其對應的控制表會更小。以下是將ASCII的資料的控制表，此控制表為一維陣列，可以在常數時間內完成轉換。在自動機程式設計及程式中，若相異程式狀態的個數不多，可以有效的用控制變數來建立整個程式控制流程的模型。上述一維的控制表可以視為將原始資料直接翻譯為對應副程式的數值，只是原始資料的種類不多，或者有夠快的記憶體時，此作法可以快速的進行資料驗證及對應副程式數值的轉換。分支表.是由連續的機械碼branch或jump指令組成的一維陣列，其目的是可以進行，依編號執行對應的指令。有時編譯器最佳化處理時，若輸入值的範圍不大，也可能會用分支表來實現codice_1指令。分支表比一連串的codice_2指令要短，但分支指令碼仍然會重複出現，而上述的控制表只包括副程式編號，執行上所需時間會分支表要短。多維陣列.控制表常常也可以視為是真值表或是的可執行版本。控制表中常包括了命題及一到多個的對應行動。行動一般會是通用的副程式或是客戶建立的副程式，程式扮演類似「直譯器」的作用，依命題是否符合執行對應的行動，程式類似一個虛擬機器，執行控制表的內容，其抽象化的程度較高。多維陣列的控制表也可以用程式語言中的switch指令來代替，而其條件可以利用邏輯運算的AND和OR指令組合出複雜的條件，條件成立時也可以執行不止一個的副程式。不過各高階語言中的switch指令在語法上可禸能仍然有些差異，而且可能有些語言的switch指令不允許複雜的條件。相較於switch指令，控制表沒有程式語言的相依性，在處理上會比較單。控制表的內容.控制表保留了傳統程式的本質，去除了程式語言的語法及和平臺有關的成份。控制表的結構本身隱含了有關的程式，包括比較是否相等、執行副程式等。多維的控制表至少會包括一組數值和動作，可能還會有額外的運運算元或其他資訊，例如輸入或輸出資料的位置、長度及格式，供控制表相關程式進行資料轉換。控制表可能會包括索引或指向要執行副程式的指標或相對位置。以下舉例用的控制表只接受一個輸入。控制表結構中隱含的條件及動作控制表可以包含的資料種類和使用的程式語言有關，組合語言沒有資料型態的限制，允許的資料最多，其至在動作部份可以包括對應的程式碼位址。一般控制表會包括各個可能的數值及對應副程式的指標。若有些語言沒有指標的概念，則其動作部份可以用一個程式碼的編號表示，再用switch指令執行對應的副程式。控制表中可以加入註解或其他文字說明，可以使控制表除了包括其程式邏輯以外，也會提昇其可讀性。若是在程式開發前就已製作手寫的決策表，列舉不同的情形及其動作時，控制表可以用來比對是否符合原始程式規格。控制表中也可以包括一些計數器，提供不同情形的統計資訊，可以在程式執行中自動進行最佳化，或是之後由人工修改程式，進行最佳化。控制表可以當成程式的靜態變數，利用文字檔儲存，放在資料庫中，也可以在程式啟動時依引數動態建立。效能考量.乍看之下，使用控制表會增加，因為需要一個程式來查表及執行對應的副程式。不過將執行的程式及用表格表示的邏輯分開，可以更清楚的讓每個程式執行各自的機能。就像是試算表的應用程式一様，為了顯示其結果，試算表軟體將複雜的公式變成可以有效用表格顯示的方式。控制表的例子.以下的範例是以四則運算為例，為簡單起見只接受一個輸入，範例的目的只是展示如何用控制表來取代一般程式的指令來調整控制流程。控制表也可以接受多個輸入，若利用有層次的連結式控制表，也可以達到結構化程式設計的目的。CT1的控制表是一個簡單的查詢表，第一欄是要測試的資料，若資料等於第一欄的數值，會執行第二欄指定的副程式。實務上這就是一個多路分支的形式來進行，也是一種的形式，最後一列是對應資料不符合任一數值時的處理。CT1static const char CT1[] = { "A", "S", "M", "D" }; /* permitted input values */static const void *CT1p[] = { &amp;&amp;Add, &amp;&amp;Subtract, &amp;&amp;Multiply, &amp;&amp;Divide, &amp;&amp;Default}; /* labels to goto &amp; default*/for (int i = 0; i  default label */若控制表改為一個有256個元素的一維陣列，直接將數值轉換為對應副程式的編號，即利用元素大小為位元組的陣列進行，可以在常數時間 formula_1內找到對應的副程式，CT1p陣列也可以用指向副程式的指標代替標記，就不需用到goto指令，但因為呼叫副程式需要的較多，會對程式效能略為影響。static const void *CT1p[] = {&amp;&amp;Default, &amp;&amp;Add, &amp;&amp;Subtract, &amp;&amp;Multiply, &amp;&amp;Divide};/* the 256 byte table, below, holds values (1,2,3,4), in corresponding ASCII positions (A,S,M,D), all others set to 0x00 */static const char CT1x[]={'\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x01','\x00','\x00','\x04','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x03','\x00','\x00','\x00','\x00','\x00','\x02','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x03','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00','\x00'};/* the following code will execute in constant time, irrespective of the value of the input character (x) */i = CT1x(x); /* extract the correct subroutine index from table CT1x using its ASCII value as an index initially */goto *CT1p[i]; /* goto (Switch to) the label corresponding to the index (0=default,1= Add,2= Subtract.) - see CT1p */以下的例子說明只要程式語言支援依編號分支到各副程式的語法，就可以達到類似上述程式的二維控制表的效果。下例中用陣列CT2來決定指標陣列CT2P的編號，若程式語言不支援指標陣列，也可以用類似SWITCH指令的方式處理，SWITCH指令中可以直接處理輸入，或是跳到對應的副程式再處理輸入。CT2CT2P 指標陣列以下的例子不使用實際的程式碼，只用二個陣列來表示，只要是支援依編號分支到陣列中的編號，若此程式語言不支援指標，也可以用類似SWITCH指令的作法取代CP2陣列的查表，依序將輸入值和每一個可能的資料比對，若資料符合，跳到對應的副程式中。CT2此例可以在不使用查表法的情形下，很有效率的將ASCII輸入資料轉換為指標陣列的編號，不過為了和上例一致，仍使用陣列表示。CT2P 指標陣列也可以配合實際的應用，創造有更多欄位的控制表，控制表會比上例複雜，但可以在更多測試輸入時有更多測試條件的組合，而不是隻比對單一測試條件。以下的控制表有增加一個輸入資料，若輸入滿足其中一個資料，該測試條件就成立，也就會進行對應的動作，另外也增加一欄來計算實際執行時各個條件成立過幾次。CT3上述的控制表更接近過程化程式設計中用到的條件指令，不過實際語言中用到的一些指令已轉換為處理控制表的「直譯器」程式，控制表只看到各個輸入及其對應的副程式編號。結構化程式設計或是「無Goto程式碼」也可以配合經過適當設計及縮排的控制表結構使用。表格驅動評級.在電信領域中決定一通電話特定費率的「電信評級」應用中，「表格驅動評級」技術描述將控制表應用在規則可能常常會因為市場外力而進行調整的情形，在許多情形下，決定計費的表格會由非程式設計者花一點時間進行修改及維護，更改需要的時間很短。若其演演算法不是事先建在直譯器中，而是由程式決定此演演算法，此技術稱為「以規則為基礎的評價」，但和表格驅動評級比較，前者的更高。試算表.試算表可以看成是一種二維的控制表，其非空白的儲存格中有資料，而試算表的程式即為直譯器。有公式的格子一般前面會前置一個等號，表示這是特殊形態的輸入，在處理中可能還會用到其他儲存格的資料。試算表和上述的「以規則為基礎的評價」有很相近的地方，就是控制表的外化，即使是非程式設計者也能進行維護。程式設計範型.和控制表最接近的程式設計範型是自動機程式設計或是反射的超程式設計。不過控制表的直譯器及各副程式可以用任何一種或多種程式設計範型來開發。表格本身可以只是原始資料的集合，不需要編譯，在使用時再從外部裝置中讀取即可，不過表格放在記憶體中的效率會比較高。和位元碼/虛擬機器指令集的對照.多維的控制表在概念上類似在虛擬機器上運作的位元組碼，虛擬機器是一個跨平臺的「直譯器」軟體，要執行一,一些對應的程式，而要執行的內容是依表格內容所決定。控制表的概念也有些類似通用中間語言，其目的都在建立一個共用的跨平臺的「指令集」。監控控制表的執行情形.直譯器也可以儲存各階段的程式計數器內容或是其他資料，來記錄部份或完整程式的流桯，記錄的目的可以為了偵錯的需要、偵測、程式碼覆蓋的分析及效能分析，像上述CT3的例子就可以計數各個動作執行過的次數。