Thread: Breaking a for loops when result reached

  1. #1
    Registered User
    Join Date
    Aug 2003
    Posts
    12

    Breaking a for loops when result reached

    I'm having a mental block at the moment. Basically I have a collection of objects so I'm wanting to loops through the collection until a certain set of values are reached and then return the Index of the item which meets this criteria.

    Problem is if i'm correct it will return every time it gets to the next item in the loop thereby re-setting the value of the returned item.

    Therefore i need a method of breaking out of the for loop once the correct item has been returned.

    I've tried the following code, problem being is that the "break" statement is quite unreachable and I can't for the life of me how to rectify this.

    Code:
    public int CurrentIndex()
    {			
                    for(int n=0;n<Images.Count;n++)
    	{					
    	               if(Images[n].PosX == 0 & Images[n].PosY == 0)
    		{
    			return Images.IndexOf(Images[n]);
    			break;
    		}
    		else
                                                    return -1;
    	}
    }
    Oh and it also complains about not all code paths returning a value which is true i suppose.

  2. #2
    pronounced 'fib' FillYourBrain's Avatar
    Join Date
    Aug 2002
    Posts
    2,297

    Re: Breaking a for loops when result reached

    Code:
    public int CurrentIndex()
         {
         int retval = -1;			
         for(int n=0;n<Images.Count && retval == -1;n++)
              {					
              if(Images[n].PosX == 0 & Images[n].PosY == 0)
                   retval = Images.IndexOf(Images[n]);
              }
         return retval;
         }
    edit: the reason I changed it this way is that I HATE things that break the proper flow of a function. Meaning, there should be a begin, end and a set of paths to get there but NEVER jumps. so, what that means is no gotos, breaks ("case" being an exception), returns, etc... in the middle of functions.
    Last edited by FillYourBrain; 08-14-2003 at 08:10 AM.
    "You are stupid! You are stupid! Oh, and don't forget, you are STUPID!" - Dexter

  3. #3
    jasondoucette.com JasonD's Avatar
    Join Date
    Mar 2003
    Posts
    278

    Re: Breaking a for loops when result reached

    When a function calls return, the function quits, and thus the loop and whatever code that was in the function has all been terminated. Return means to quit the function immediately and return that value. Therefore, you do not need a break command to stop the loop. So, basically, modify your code like so:

    Code:
    public int CurrentIndex()
    {			
                    for(int n=0;n<Images.Count;n++)
    	{					
    	               if(Images[n].PosX == 0 & Images[n].PosY == 0)
    		{
    			return Images.IndexOf(Images[n]);
    			//break; - NOT NEEDED
    		}
    		// else - DO NOT NEED AN ELSE
                                                    // return -1; - WRONG PLACE
    	}
    	return -1; // RIGHT PLACE
    }
    Also, the return -1 command was in the wrong place - after your first test to see if the current object is the correct one, you either return it or -1, without ever checking any other objects. So, remove the else part of the if statement. Let the loop continue through, and if an object is found, then return quits the whole function immediately. If no object is found, the loop goes through completely, and continues on with whatever statements that follow it. So, at this point, you can return -1 to indicate nothing was found.

    (EDIT: I agree with what FillYourBrain is saying about improper breaking of loops/functions. But if they are simple enough, there should not be any problem using a return in the middle of one for loop.)

  4. #4
    Registered User
    Join Date
    Aug 2003
    Posts
    12
    Cheers bud, think In was being dumb anyway, why the hell would I need a break when return is just the equivalent. Oh i'm not sure but I think I might have spotted an error in your code.

    Code:
    int retval = -1;			
    for(int n=0;n<Images.Count && retval != -1;n++)
    Surely thats saying while n is less than the count AND retval is not -1. Well won't retval always be -1 at this point and therefore never enter the for loop in the first place it not until here that you reset the value of retval.

    Code:
    if(Images[n].PosX == 0 & Images[n].PosY == 0)
                   retval = Images.IndexOf(Images[n]);
    Is that correct or am I being dumb again???

  5. #5
    pronounced 'fib' FillYourBrain's Avatar
    Join Date
    Aug 2002
    Posts
    2,297
    no, your right retval == -1 is what you want. I'll change it above.
    "You are stupid! You are stupid! Oh, and don't forget, you are STUPID!" - Dexter

  6. #6
    Registered User
    Join Date
    May 2003
    Posts
    1,619

    Re: Re: Breaking a for loops when result reached

    I like this code best, with the one modification (although it should work either way):

    Originally posted by JasonD
    Code:
    public int CurrentIndex()
    {			
    	for(int n=0;n<Images.Count;n++)
    	{					
    		if(Images[n].PosX == 0 && Images[n].PosY == 0)
    		{
    			return Images.IndexOf(Images[n]);
    		}
    	}
    	return -1;
    }
    I don't agree with FYB's dislike of breaking or returning in mid-loop. I would agree if we were talking about x86 assembly language; in that, you want to write the cleanup and return code only once for each function. But this is not x86 assembler, and every necessary cleanup before return should, if you program correctly, be automatic.

    I think adding flag variables and returning in exactly one point often serves to obfuscate code, and it often leads to deeper if-else nesting. On the other hand, abuse of breaking, returning in a loop, etc. are also bad style.

    I think there is no hard and fast rule of thumb; go with whatever code offers maximum readability. I never recommed gotos, those are completely unneeded in C++ (they are NEVER the most readable solution), but commands to prematurely end loops (break), to prematurely end a function (return or throw), etc. are very useful. Like anything else, you can abuse them, but I think it's a little foolish to disavow ever using a language construct when it makes the program more readable.

    In this case, I find the above code more readable than FYB's, although of course both can be understood and both accomplish the same goal. And if we were returning an object, and not an int, the above code could be more efficient because unnamed copies of objects can often be optimized away by the compiler. This code also requires two fewer compare/jump pairs as c0ompared to FYB's, which can slow down code (especially when branch prediction fails, as it will when you exit a loop). Granted, the performance difference is almost certainly so small as to be totally negligable, except when returning objects.

    My rule of thumb, which is always my rule of thumb for everything, is "use it -- don't abuse it." Write in a way that makes the program most clear. Sometimes that means breaking from loops; sometimes it means not breaking from loops.
    Last edited by Cat; 08-15-2003 at 10:46 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Inserting a swf file in a windows application
    By face_master in forum Windows Programming
    Replies: 12
    Last Post: 05-03-2009, 11:29 AM
  2. Need help with basic calculation program.
    By StateofMind in forum C Programming
    Replies: 18
    Last Post: 03-06-2009, 01:44 AM
  3. Promblem with code
    By watchdogger in forum C Programming
    Replies: 18
    Last Post: 01-31-2009, 06:36 PM
  4. Type casting
    By Lionmane in forum C Programming
    Replies: 28
    Last Post: 08-20-2005, 02:16 PM
  5. Output problems with structures
    By Gkitty in forum C Programming
    Replies: 1
    Last Post: 12-16-2002, 05:27 AM