2010-08-03 4 views
1

다음과 같은 간단한 재귀를 가정 해 보겠습니다.간단한 재귀 질문

int x(int a){ 
    if(a<10) 
    x(a+1); 
    else 
     !STOP! 
    b++; 
return b; 
} 

Globaly 다음 p는,이 수단 0이 될 수 있도록

int p=x(1); 

가되는 재귀를 중지 할 수있는 방법을 : 주에서

int b=0; 

우리가 이런 일을 할 수 "b ++"는 절대로 실행되지 않을 것입니다.

! 대신에! expopion을 넣어 주시면 감사하겠습니다.

그러나 나는 이런 식으로하고 싶지 않습니다. 그냥 휴식과 같은 재귀를 멈추고 싶습니다. while() 루프에서 않습니다 : ... :

int ok=0; 
    int x(int a){ 
     if(a<10) 
     x(a+1); 
     else 
      ok=1; 
     if(ok==0) 
     b++; 
    return b; 
    } 

질문에 대해 명확하지 않은 것이 있으면 질문하십시오.

+0

아, 그리고이 재귀를 중지 의미 때 나는 또한 스택 ... – Cristy

+0

Cristy 삭제보기 자동 의미, 당신은 주석을 추가하기보다는 질문을 편집 할 수 있습니다. –

+0

왜이 작업을 수행 하시겠습니까? 당신이 직업에 대해 잘못된 도구를 사용하고있는 것처럼 보이지만, 당신이 계획하고있는 것에 대한 구체적인 예를 없이는 말하기 어렵습니다. –

답변

7

왜 이렇게하지 않습니까?

int x(int a){ 
    if(a<10) { 
     x(a+1); 
     b++; 
    } 
    return b; 
} 

하지만, 특히 스레드 안전하지 않고 상당히 엉성하지 않은 재귀 루틴에서 전역을 수정하고 있습니다. 최상위 호출자를 제외하고 항상 무시되는 값을 반환합니다. 당신은 또한 루프에서 수행하는 것이 더 낫다 (하지만 실제 사례가 이보다 크거나 학생이라고 생각합니다.).

정말 재귀를 "중단 할"수 없습니다. oldey-timey C에서는 setjmp/longjmp (그리고 그 모든 위험 - 다른 말로하면 안됨)를 사용할 수 있고, C++에서는 try/catch/throw를 사용할 수있다. 그러면 try/catch/throw가 스택을 풀 수도있다.

+0

답변 해 주셔서 감사합니다! 그래서 ideea는 재귀를 "끊을"수 없다는 것입니다 ... 어쨌든, 이것을하기위한 ideea는 쓸모없는 계산에서 프로그램을 막는 것이 었습니다 ... 내 말은, 내가 필요했던 재귀를 가질 수 있음을 의미합니다. 모든 길을 앞으로 나아가고, 나머지 반을 "재귀"하지 않고 반 복습을 멈추기 위해 되돌아 올 때. 나는 너무 잘 설명 할 수는 없지만, 내가 말하는 것을 얻기를 바랍니다. D – Cristy

+1

플 린스 (plinth)는이 경우 예외를 던질 수 있다고 말합니다. –

+0

나는 던짐 & 붙잡음을 결코 사용하지 않으며 나는 과거 2 년에서 많이 프로그래밍하고있다. 나는 그것에 대해 정말로 읽어야한다는 것을 의미한다. :) – Cristy

1

어때?

int x(int a){ 
    if(a>0 && a<10) 
    x(a+1); 
    b++; 
    return b; 
} 
+0

이 코드는 b ++ 만 실행합니다. 함수를 x (1)이라고 부르면 1 번 씁니다. 1 <0 && 1 <10은 false입니다. 이것은 단지 재귀를 입력하는 기능을 중지합니다, 그것은 시작되면 "돌아 가기"재귀를 중지하지 않습니다 ... – Cristy

+0

@ 제리 미안 해요, 그것에 대해, 내 오타가 수정되었습니다. –

1

반송하는 것은 어떻습니까?

int x(int a){ 
    if(a<10) 
    x(a+1); 
    else 
     return b; 
    b++; 
return b; 
} 

내가이 조금 더 나은 모습 생각

int x(int a){ 
    if(a<10) 
    x(a+1); 
    else 
     return b; 

    return ++b; 
} 

편집 : 당신은, 스택을 풀고 첫 번째 호출 지점에 도착하는 예외 메커니즘을 사용할 수 있다고 생각

하지만, main()을 입력 한 후에는 안전합니다. 코드 주어진, x에서 b을 참조 :

int b = 0; 
int p = x(1); 

x 일부 전역 변수의 초기화에 사용되며 main() 전에 실행할 수 있음을 시사한다. try-catch 블록에서 x의 호출을 감싸고 | STOP | 대신에 예외를 던지는 일부 도우미 함수를 사용하는 방법은 어떻습니까?

+1

이 생각은 전체 계산을 취소하고 중간 결과를 무시하고 모든 추가 처리를 중단 할 수 있어야합니다. 'return'은 계산이 더 많은 재귀를 계속하는 것을 막습니다. –

+0

@David Thornley 알겠습니다, thx :) –

+0

리턴을 사용하면 함수의 현재 호출을 중지하고 계속 돌아가서 재귀를 계속할 것입니다 ... 말하면, 멈출 것입니다! 나는 정말로 멈추다 : D. (완전히 재귀 호출을하지 않고 함수를 종료하고 스택을 지우십시오 ...) – Cristy

1

스택을 푸는 C++의 유일한 예외는 예외입니다. setjmp()/longjmp()도 있지만 C++ 프로그램에서는 절대로 사용해서는 안됩니다. 다른 모든 구성은 현재 함수에서 반환 할 수 있습니다.

0

bmain()에 신고하고 bx()에 사용하려는 경우 이미 잘못된 것이 있습니다. 대신 x에 매개 변수로 전달하고 b의 수정 된 버전을 반환하여 b을 로컬 변수로 만듭니다.

int x(int a, int b){ 
    if(a<10) 
     return x(a+1,b+1); 
    else 
     return b; 
} 
+0

이것은 내가 만든 빠른 예입니다. 나는 그것을 b ++에 넣었다. 함수에서 recursion-call 뒤에 함수가 실행되고 싶지 않을 것임을 보여주기 위해 ... :) – Cristy

+0

프로그램이 그것을 반환하면 중복되므로 다른 것을 제거 할 수도 있습니다 아래 코드를 실행하지 않습니다. – ChickSentMeHighE

+0

@ChikSentMeHighE : nitpick하지 마세요. ( –

0

저는 제어를 위해 예외를 사용하는 것을 크게 좋아하지 않습니다. if/return 문 대신 Exceptions를 사용하면 많은 사이클을 절약 할 수 있다고 기대하지 않습니다. 어쨌든 예외를 던지기 전에 경계 조건을 테스트해야합니다.

그러나 함수의 반환 형식을 변경하면 문제를 간단하게 단순화 할 수 있습니다.

bool x(int a){ 
    if(ok) //Exit early before next call up? 
    return true; 
    if(a<10){ 
    if(x(a+1)) //Have we been told to exit early? 
     return true; //Yes 
    b++; //Do some work 
    if(ok) //Exit early in the next call down? 
     return true; 
    } 
    return false; //Normal Exit 
} 
+0

좀 지저분하고 재귀를 "멈추지"않습니다. D ... 도움을 주셔서 감사합니다 :). – Cristy

+0

이것이 재귀를 "멈추지"않는 방법을 설명해 주시겠습니까? –