我有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()
才能達到這個目的?
我有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()
才能達到這個目的?
那麼,有直接使用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_fun1
,my_fun2
和my_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();
}
是的,可以通過拋出異常並在main
中捕獲該異常。但請不要將異常用作通用控制流程機制,這不是他們的目的。
還有setjmp
/longjmp
,但使用它們的代碼很難遵循。
所有功能要麼返回或拋出和捕捉異常(不推薦,除非上去堆棧的原因確實是錯誤的情況)
不濫用異常乾淨的方法是
#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;
...
}
注意:只有在調用後面有代碼時才需要if條件。 –
'#define','void main' - 你真的要教壞習慣嗎? – MSalters
看來你可能暗示goto
這是不好的。
沒有看到你的程序結構,你可以考慮一個返回布爾值(例如一個標誌),它在從#2中檢測到的函數#3返回時被檢查,該函數然後返回,在#1中檢查,然後返回到main()
。
通過拋出一個異常是可能的,就像larsmans說的(儘管只用C++)。也可以通過setjmp()/ longjmp(),它作爲一種跨功能goto語句。
但是,如果這真的是你想要/需要的設計,那麼你的設計可能有問題。在my_fun1和my_fun2中有條件可能是「正確」的答案,但這取決於你在做什麼,當然。如果您發佈了更多關於爲什麼您可能需要/需要的信息,我們可能會更好地爲您提供幫助。
只需將您的第一個函數調用放入循環中即可。無論如何,這是普遍接受的編程方法之一。
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()在此基礎上的行爲,那麼你的情況中止做的事情或者是一個錯誤,或者是基本上就像一個錯誤,所以拋出一個異常將是一個更好的解決方案。即使它不是一個錯誤,它仍然基本上是相同類型的控制邏輯。但是,如果這是程序的非錯誤控制流程,則可能需要更多地查看結構並找出導致您需要這樣做的原因,並儘量避免造成邏輯錯誤的原因這個。
謝謝。我的代碼目前這樣做(從每個函數返回布爾值),但我只是想知道是否有更直接的方法。但正如你們大多數人所建議的那樣,另一種方式是拋出異常,所以我不認爲我會改變我的代碼。 –