2009-06-30 42 views
0

函數調用後,C++是否有任何類型的實用程序返回函數的開頭?例如,例如在計算函數中調用help()。返回函數開頭的方法

void help() 
{ 
    cout << "Welcome to this annoying calculator program.\n"; 
    cout << "You can add(+), subtract(-), multiply(*), divide(/),\n"; 
    cout << "find the remainder(%), square root(sqrt()), use exponents(pow(x,x)),\n"; 
    cout << "use parentheses, assign variables (ex: let x = 3), and assign\n"; 
    cout << " constants (ex: const pi = 3.14). Happy Calculating!\n"; 
    return; 
} 

void clean_up_mess()  // purge error tokens 
{ 
    ts.ignore(print); 
} 

const string prompt = "> "; 
const string result = "= "; 

void calculate() 
{ 
    while(true) try { 
     cout << prompt; 
     Token t = ts.get(); 
     if (t.kind == help_user) help(); 
     else if (t.kind == quit) return; 
     while (t.kind == print) t=ts.get(); 
     ts.unget(t); 
     cout << result << statement() << endl; 
    } 
    catch(runtime_error& e) { 
     cerr << e.what() << endl; 
     clean_up_mess(); 
    } 
} 

雖然在技術上我的幫助功能的實現工作正常,但並不完美。在呼叫幫助後,返回,繼續嘗試cout < <結果< < statement()< < endl;這是不可能的,因爲沒有輸入數值。因此它給出了一點錯誤信息(程序中的其他地方),然後繼續執行程序。功能沒問題,但它很醜,我不喜歡它(:P)。

那麼當幫助函數返回時,還有什麼辦法可以回到計算開始並重新開始嗎? (我在if(t.kind == help_user)塊中插入一個函數調用來調用calculate,但是正如我認爲這只是延遲問題而不是解決它。)

+0

或者,如果你只是滾動下來一點,你會發現,你可以做到這一點不只是一個簡單的改變你的邏輯繼續下去,如不執行代碼,你不想... – stefanB 2009-06-30 03:41:37

回答

5

您可以使用goto,但你做的那一刻認爲自己過。這被認爲是不好的做法,它的良好用途是罕見的和相距甚遠的。

我想你要找的是什麼繼續:

void do_calculate(void) 
{ 
    while (true) 
    { 
     cout << prompt; 
     Token t = ts.get(); 

     if (t.kind == help_user) 
     { 
      help(); 
      continue; // <- here 
     } 
     else if (t.kind == quit) 
     { 
      return; 
     } 

     while (t.kind == print) 
     { 
      t = ts.get(); 
     } 
     ts.unget(t); 

     cout << result << statement() << endl; 
    } 
} 

void calculate() 
{ 
    try 
    { 
     do_calculate(); 
    } 
    catch (const std::exception& e) 
    { 
     cerr << e.what() << endl; 
     clean_up_mess(); 
    } 
} 

我也重新格式化你的代碼。我認爲這是更可讀的,每個人都有自己的想法,但只是想讓你比較。

  • try/catch子句現在不再幹擾計算功能。

  • 'if'語句使用括號來保持一致性。此外,它更容易閱讀,因爲我知道無論是如何控制是在這些括號內。

  • catch將捕獲std :: exception,而不是runtime_error。所有的標準異常繼承自std :: exception,所以通過捕獲你知道你可以捕獲任何東西。

+0

所有優秀的答案!我只是選擇了這個,因爲它在頂部:P 從來不知道繼續,但現在我非常感謝! – Alex 2009-06-30 03:36:16

5

這可能是你尋找?

if (t.kind == help_user) { 
    help(); 
    continue; 
} 
+0

所有偉大的答案!我只是選擇了另一個,因爲它在頂部:P從來不知道繼續,但現在我非常感謝! – Alex 2009-06-30 03:38:07

2

您可以使用continue語句返回到循環的頂部。這是達到你想要什麼,最簡單的方法,因爲你有一個while環周圍代碼:

if (t.kind == help_user) { 
    help(); 
    continue; 
} 

另外還有goto聲明雖然這幾乎總是一個壞主意。我會讓你自己閱讀。欲瞭解更多信息,請閱讀「控制流程」。

在這種特定的實例,我可能會選擇只是通過增加一個else語句,像這樣重組你的代碼稍微:

if (t.kind == help_user) 
     help(); 
    else if (t.kind == quit) 
     return; 
    else { 
     while (t.kind == print) 
      t=ts.get(); 
     ts.unget(t); 

     cout << result << statement() << endl; 
    } 
+0

所有優秀的答案!我只是選擇了另一個,因爲它在頂部:P 從來不知道繼續,但現在我非常感謝! – Alex 2009-06-30 03:37:23

1

是的,它被稱爲邏輯:

void calculate() 
{ 
    while(true) 
    { 
    try { 
     cout << prompt; 
     Token t = ts.get(); 
     if (t.kind == help_user) 
      help(); 
     else 
     { 
      if (t.kind == quit) return; 
      while (t.kind == print) t=ts.get(); 
      cout << result << statement() << endl; 
     } 
     ts.unget(t); // if statement above needs this then leave it in and 
         // add one call after help() as well ... not sure from code 
    } 
    catch(runtime_error& e) { 
     cerr << e.what() << endl; 
     clean_up_mess(); 
    } 
}