2011-07-14 8 views
1

私は3つの関数:my_fun1(),my_fun2()、およびmy_fun3()を持っています。ユーザ定義関数からmain()に移動

main()my_fun1()を呼び出してmy_fun2()を呼び出し、次にmy_fun3()を呼び出します。

my_fun3()の定義済みの条件では、my_fun1()という行でmain()関数に直接戻ります。

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_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(); 
} 
+0

ありがとうございます。私のコードは現在これを行います(各関数からboolを返す)が、より直接的な方法があるかどうかを知りたいだけでした。しかし、あなたの大部分が示唆しているように、もう1つの方法は例外をスローすることでしたので、私は自分のコードを変更するつもりはないと思います。 –

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が悪いことを示唆しているようです。

プログラムの構造が見えない場合は、関数#3から戻ったときにチェックされる戻りブール値(たとえばフラグ)が考慮され、#2でチェックされ、#1でチェックされ、 main()に戻ります。

0

larsmansのように例外をスローすることができます(C++のみ)。 setjmp()/ longjmp()はクロス関数のgoto文の一種として機能します。

これが実際にあなたが望む/必要とするデザインであれば、おそらくデザインに何か問題があります。 my_fun1とmy_fun2の条件はここでは「正しい」答えかもしれませんが、もちろんあなたがやっていることに依存します。あなたがなぜこのようなことが必要なのか、なぜ必要なのかについてのより詳しい情報を投稿すれば、あなたをより良く助けることができるかもしれません。

0

最初の関数呼び出しをループに入れてください。それはとにかく一般的に受け入れられているプログラミング方法の1つです。

main 
    while running 
     do stuff 

だから、

bool running = false; 

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

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

を行うことができますが、この動作は、自分の状況に基づいて何かを中止するためにはfunction1()と機能2を()が必要な場合のいずれかのエラーがあるか、エラーのように、基本的です、例外をスローするとより良い解決策になります。たとえそれがエラーではないとしても、それは基本的には基本的に同じタイプの制御ロジックです。

しかし、これがプログラムのエラーのない制御フローであれば、構造をもっと調べて、何が原因でこのようにする必要があるのか​​把握し、どのようなロジックこの。

関連する問題