views:

235

answers:

6

Let's say we have a simple recursion like.

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

Globaly:

int b=0;

In main we could have something like this:

  int p=x(1);

Is there any way to stop the recursion so that the p will be 0, this means that "b++" will never be executed.

I'll be grateful if you could tell me some expresion to put instead of the !STOP!

But, I don't want anything like this, I just want to stop the recursion, like break; does in a while() loop...:

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

If there's anything unclear about the question, just ask.

+1  A: 

How about like this?

int x(int a){
   if(a>0 && a<10)
     x(a+1);
   b++;
   return b;
}
rlb.usa
Cristy
@Jerry sorry, about that, fixed my typo.
rlb.usa
+7  A: 

Why wouldn't you do this?

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

The thing is, though, you're modifying a global in a recursive routine, which is not especially threadsafe and pretty sloppy. You're returning a value that is always ignored except by the top level caller. You're also doing something that is better off being done in a loop (but I assume that your actual case is bigger than this, or you're a student).

You can't really "break" the recursion - returning unwinds well enough. In oldey-timey C you might use setjmp/longjmp (and all its perils - in other words, DON'T), and in C++ you might use try/catch/throw, which will unwind the stack as well.

plinth
Thanks for the answear! So the ideea is that I can't "break" a recursion...Anyway, the ideea to do this was to stop the program from useless calculations...I mean, I could have a recursion that was needed to go all the way forward, and then, when coming back to stop half-way the recursion, without "recursing" through the remaining half. I can't explain too good, but I hope you get what I'm saying :D
Cristy
As plinth say, you could throw an exception in this case.
jon hanson
Cristy
Although you *could* use an exception here, you really *shouldn't*. Exceptions should be for *exceptional* (i.e. rare, unexpected) situations. They should not be used for flow control.
Tyler McHenry
I think bailing out of a recursive call stack is an ideal use for an exception.
jon hanson
@Tyler: Exceptions will also be a very slow way to do flow control. I once took some code that had an exception for flow control in a tight inner loop, refactored it and made it hugely faster.
Ken Bloom
+1  A: 

How about returning?

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

I think this looks a bit better

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

    return ++b;
}

EDIT:

I think You could use exception mechanism to unwind the stack and get to the point of first invocation, but it's safe after entering main(). Referencing b in x, given the code:

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

suggests that x is used for initialization of some global variable and may be executed before main(). How about using some helper function that wraps invocation of x in a try - catch block and throwing an exception in the place of |STOP|?

Maciej Hehl
The idea, I believe, is to be able to cancel the whole calculation, discard intermediate results, and abort all further processing. `return` just stops the calculation from continuing with more recursion.
David Thornley
@David Thornley I see, thx :)
Maciej Hehl
If I'll use return it will just stop the current call of the function to continue and will go back and continue the recursion... I mean, when I say !STOP! I really mean stop :D. (totally exit the function with no future calls from the recursion,clear the stack...)
Cristy
+1  A: 

The only thing in C++ that will unwind the stack like that is an exception. There's also setjmp()/longjmp(), but those should never be used in a C++ program. Any other construct can at most return from the current function.

David Thornley
A: 

If you're trying to declare b in main(), and use b in x() then there's something wrong already to begin with. Instead, make b into a local variable by passing it as a parameter to x, and returning a modified version of b.

int x(int a, int b){
   if(a<10)
      return x(a+1,b+1);
    else
      return b;
}
Ken Bloom
That is just a fast example I've created. I've put that b++; in the function to show that there would be some code after the recursion-call inside the function that I'll don't want be executed... :)
Cristy
You can also remove the else since it's redundant, once the program returns it will never run the code below.
MikeAbyss
@ChikSentMeHighE: don't nitpick :(
Ken Bloom
A: 

I'm not a big fan of using an Exception for control. I don't expect you'll save many cycles by using Exceptions instead of if/return statements. You're going to have to test your boundary conditions anyway before throwing an Exception.

You can however simplify the problem a bit by changing the return type of the function.

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
}
Thomas Langston
That's a little messy, and still doesn't "stop" the recursion :D...Thanks for help anyway :).
Cristy
Could you explain how this doesn't "stop" the recursion?
Thomas Langston