2011-07-14 87 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()在此基础上的行为,那么你的情况中止做的事情或者是一个错误,或者是基本上就像一个错误,所以抛出一个异常将是一个更好的解决方案。即使它不是一个错误,它仍然基本上是相同类型的控制逻辑。但是,如果这是程序的非错误控制流程,则可能需要更多地查看结构并找出导致您需要这样做的原因,并尽量避免造成逻辑错误的原因这个。