2011-07-14 40 views
1

我有3個函數:my_fun1(),my_fun2()my_fun3()從用戶定義函數轉到主函數

main()調用my_fun1()它調用my_fun2(),它又調用my_fun3()

根據my_fun3()中的一些預定義條件,我希望我的程序直接返回main()函數,在線路my_fun1()被調用。

是否可以直接從my_fun3()main(),還是我必須添加一些條件到my_fun2()my_fun1()才能達到這個目的?

回答

4

那麼,有直接使用longjmp/setjmp代碼跳轉到另一點的方式,但我不會告訴你如何,因爲這是一個可怕的想法。幾乎和它一樣糟糕。所以讓我們來談談好的解決方案:-)。

最明顯的方法是使用例外。就像這樣:

int my_fun3() { 
    throw 1; // could be any type... 
} 
int my_fun2() { 
    my_fun3(); 
} 

int my_fun1() { 
    my_fun2(); 
} 

int main() { 
    try { 
     my_fun1(); 
    } catch(int n) { // catch the same type you threw... 
    } 
} 

如果你不想使用異常,(這可能是這種情況,有些人可能會認爲,這將是例外的濫用,如果要回到主的原因不「例外」)下一個最直接的方法是使my_fun1my_fun2my_fun3的返回值表示「完成」,假設一個int,其中小於0的值表示「返回主」。您的通話結構如下所示:

int my_fun3() { 
    // ... 
    if(some_condition) { 
     return -1; 
    } 

    return 0; 
} 

int my_fun2() { 
    // ... 
    int r = my_fun3(); 
    if(r < 0) { 
     return r; 
    } 
    // ... 
    return 0; 
} 

int my_fun1() { 
    // ... 
    int r = my_fun2(); 
    if(r < 0) { 
     return r; 
    } 
    // ... 
    return 0; 
} 

int main() { 
    my_fun1(); 
} 
+0

謝謝。我的代碼目前這樣做(從每個函數返回布爾值),但我只是想知道是否有更直接的方法。但正如你們大多數人所建議的那樣,另一種方式是拋出異常,所以我不認爲我會改變我的代碼。 –

3

是的,可以通過拋出異常並在main中捕獲該異常。但請不要將異常用作通用控制流程機制,這不是他們的目的。

還有setjmp/longjmp,但使用它們的代碼很難遵循。

3

所有功能要麼返回或拋出和捕捉異常(不推薦,除非上去堆棧的原因確實是錯誤的情況)

0

不濫用異常乾淨的方法是

#define EXITCONDITION 42 

void main() 
{ 
    ... 
    myfunc1(); 
    ... 
} 

int myfunc1() 
{ 
    ... 
    if (myfunc2() == EXITCONDITION) return EXITCONDITION; 
    ... 
} 

int myfunc2() 
{ 
    ... 
    if (myfunc3() == EXITCONDITION) return EXITCONDITION; 
    ... 
} 

int myfunc3() 
{ 
    ... 
    if (somethingweirdhappens) retrun EXITCONDITION; 
    ... 
} 
+0

注意:只有在調用後面有代碼時才需要if條件。 –

+0

'#define','void main' - 你真的要教壞習慣嗎? – MSalters

0

看來你可能暗示goto這是不好的。

沒有看到你的程序結構,你可以考慮一個返回布爾值(例如一個標誌),它在從#2中檢測到的函數#3返回時被檢查,該函數然後返回,在#1中檢查,然後返回到main()

0

通過拋出一個異常是可能的,就像larsmans說的(儘管只用C++)。也可以通過setjmp()/ longjmp(),它作爲一種跨功能goto語句。

但是,如果這真的是你想要/需要的設計,那麼你的設計可能有問題。在my_fun1和my_fun2中有條件可能是「正確」的答案,但這取決於你在做什麼,當然。如果您發佈了更多關於爲什麼您可能需要/需要的信息,我們可能會更好地爲您提供幫助。

0

只需將您的第一個函數調用放入循環中即可。無論如何,這是普遍接受的編程方法之一。

main 
    while running 
     do stuff 

所以,你可以做

bool running = false; 

int main(int argc, char **argv) 
{ 
    while(running) 
     function1(); 
} 

void function3() 
{ 
    ... 
    if(whatever) 
    { 
     running = true; 
     return; 
    } 
    ... 
} 

如果你需要功能1()和函數2()在此基礎上的行爲,那麼你的情況中止做的事情或者是一個錯誤,或者是基本上就像一個錯誤,所以拋出一個異常將是一個更好的解決方案。即使它不是一個錯誤,它仍然基本上是相同類型的控制邏輯。但是,如果這是程序的非錯誤控制流程,則可能需要更多地查看結構並找出導致您需要這樣做的原因,並儘量避免造成邏輯錯誤的原因這個。