標籤:

如何優化一個讀取命令並執行的程序?

類似一個 Shell。每次讀取用戶命令,並根據命令執行具體的行為。

假設有30種命令。

我除了寫30條 if.. else if..這種東西或者30條 switch case...(如果C/C++,似乎還沒法switch 字元串)。

還有什麼最佳實踐么?

用30個派生類好像也是個不靠譜的事情,最後用來產生派生類的工廠函數還是得用 if 或者 switch,更何況要管理幾十個派生類?

謝謝


map&(void)&>&> commandCreators;


  1. 30個命令你不想寫30個派生類,但總得寫30個函數吧。
  2. 假設用戶輸入 A 1 2 ,執行 add(std::string p) 的操作,入參p是 "1 2";
  3. 再假設用戶輸入 P waa, 執行 print(std::string )的操作,入參p是 "waa";

void add(string p)
{
/* 拆 入參p ,得到兩個加數,相加並列印出結果 */
}

void print(string p)
{
//我好機智,舉了這麼一個例子
cout &<&< p &<&< endl; }

然後,你可以使用 C++標準庫中的std::function來表達以上操作了,它們都接受一個string入參,返回一個void。如果你對std::function不熟悉,我們就先用函數指針說話:

using F = void(*)(string); //對using 不熟悉?typedef void (* F)(string);

二、

收到 "A" 執行 add(...) , 收到 「P」執行 print(...),所以這是一種「映射」關係,就用std::map吧:

std::map& fs;
fs["A"] = add;
fs["P"] = print;

因為命令有參數,所以用戶輸入其實是 「A 1 2」這樣的,依據空格拆解得到 "A",這就不用講了。假設現在 cmd 變存的就是「A」,而params是 "1 2":

string cmd = ...; //"A"
string params = ...; //"1 2"
std::map&::const_iterator itr = fs.find(cmd);
itr-&>second(params); //這裡就調用了 add("1 2");


哈希表吧,類似函數派發表一樣,Key 就是命令,Value 可以是一個函數指針等等。


用字元串數組跟函數指針數組不就行了。字元串數組存放命令,函數指針數組存放對應的操作函數。


#!/bin/sh

fun1()

{

echo "$*"

}

fun2()

{

echo fun2 "$*"

}

...

fun="$1"

shift

$fun "$@"


命令和參數很多的話,可以用tried樹,可參考quagga


同樣是打表, 提供一個不是那麼主流的做法, 用flex寫tokenizer, 這個編譯成DFA, 感覺性能上不錯, 而且DSL的語法看起來也比if-else好看些

%{
int test = 0;
%}
%%
hello printf("hello
");
world printf("world
");

%%

int main() {
yy_scan_string("hello");
yylex();
return 0;
}


開始以為是性能啥的,

記得代碼之美 (豆瓣) 第八章(圖像處理中的即時代碼生成)使用的方法是動態生成啥的


C/C++ 也有 void * 可以指向函數指針,最後就變成表驅動了


直接profile啊,看哪個部分最耗時,然後分析優化


推薦閱讀:

C++的完美轉發只能針對形如T &&的形參嗎?
現在C++開發是不是都遵守C++11標準,Linux下的多線程編程是優先考慮C++11的線程庫,還是用系統線程API封裝?
大學C++應該怎麼學?
用很厚的教材學編程的時候,該如何一邊攤開書一邊敲代碼?
如何讓編譯器在預處理時在一個項目中的某些指定文件中每一個函數定義前插入一個宏?

TAG:軟體工程 | C | CC |