Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Two-iteration loop

Reply
Thread Tools

Two-iteration loop

 
 
Christopher Benson-Manica
Guest
Posts: n/a
 
      11-10-2003
I have a situation something like this:

int foo;

for( foo=bar() ; foo <= bar()+1 ; foo++ ) {
if( !baz(foo) ) break;
/* do stuff with foo */
}

The idea is that the loop happens at most twice - once for foo=bar(), and once
for foo=bar()+1. If baz(foo) fails, I know I can stop. However, I don't
think this is the "elegant" way to get this behavior - there is a break (which
might be bad style, for some), and bar() may be called three times (which
doesn't seem optimal). I thought of

int foo=bar();

do {
if( !baz(foo) ) break;
/* doo stuff with foo */
} while( foo++ == bar() );

, but it's no better (and is somewhat more obfuscated, to boot). Any
thoughts?

--
Christopher Benson-Manica | I *should* know what I'm talking about - if I
ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
 
Reply With Quote
 
 
 
 
Dave Vandervies
Guest
Posts: n/a
 
      11-10-2003
In article <boodf0$sta$(E-Mail Removed)>,
Christopher Benson-Manica <(E-Mail Removed)> wrote:
>I have a situation something like this:
>
>int foo;
>
>for( foo=bar() ; foo <= bar()+1 ; foo++ ) {
> if( !baz(foo) ) break;
> /* do stuff with foo */
>}
>
>The idea is that the loop happens at most twice - once for foo=bar(), and once
>for foo=bar()+1. If baz(foo) fails, I know I can stop. However, I don't
>think this is the "elegant" way to get this behavior - there is a break (which
>might be bad style, for some), and bar() may be called three times (which
>doesn't seem optimal). I thought of
>
>int foo=bar();
>
>do {
> if( !baz(foo) ) break;
> /* doo stuff with foo */
>} while( foo++ == bar() );
>
>, but it's no better (and is somewhat more obfuscated, to boot). Any
>thoughts?


How long is the chunk that "/*do stuff with foo*/" expands to?

If it's not too long, something like this might be a little bit cleaner
(for one thing, it makes it clear that it's a "do something again unless
baz() fails" and not a "loop until some condition is met"), though it's
not without its problems:
--------
foo=bar();
/*do stuff with foo*/
foo++;
if(baz(foo))
{
/*Note that this stuff is the same stuff we did above. If baz
returns nonzero we have to do it again.
*/
/*do stuff with foo*/
}
--------

Depending on how closely what you're doing with foo is tied to the rest
of the code there, it might be worth moving it to another function:
--------
foo=bar();
do_stuff_with(foo);
foo++;
if(baz(foo))
do_stuff_with(foo); /*again*/
--------


dave

--
Dave Vandervies http://www.velocityreviews.com/forums/(E-Mail Removed)
>You can quit emacs?

Yes, and after 12 weeks of rehab, you might even stay off the stuff.
--James Riden and Greg Andrews in the scary devil monastery
 
Reply With Quote
 
 
 
 
Ian Woods
Guest
Posts: n/a
 
      11-10-2003
Christopher Benson-Manica <(E-Mail Removed)> wrote in
news:boodf0$sta$(E-Mail Removed):

> I have a situation something like this:
>
> int foo;
>
> for( foo=bar() ; foo <= bar()+1 ; foo++ ) {
> if( !baz(foo) ) break;
> /* do stuff with foo */
> }
>
> The idea is that the loop happens at most twice - once for foo=bar(),
> and once for foo=bar()+1. If baz(foo) fails, I know I can stop.
> However, I don't think this is the "elegant" way to get this behavior
> - there is a break (which might be bad style, for some), and bar() may
> be called three times (which doesn't seem optimal). I thought of
>
> int foo=bar();
>
> do {
> if( !baz(foo) ) break;
> /* doo stuff with foo */
> } while( foo++ == bar() );
>
> , but it's no better (and is somewhat more obfuscated, to boot). Any
> thoughts?


If the value returned by bar() is loop invarient, assign it to a
variable. If bar() is an expensive (but invarient) computation this will
be a nice gain, and performing a single unnecessary check is at no cost.

You might do this:

int foo, startpos;

startpos=bar();
for (foo=startpos;foo<startpos+2 && !baz(foo);foo++) {
/* do stuff */
}

if you don't like the break. Personally, I don't mind "if (cond) break;"
especially at the beginning of loops.

If bar() isn't loop invarient and expensive, then you can still do it
nicely. something like:

int foo;
for (foo=0;foo<2;foo++) {

int barval=bar()+foo;
if (!baz(barval)) break;

/* do stuff */
}

If bar() isn't expensive and loop invarient, it doesn't really matter if
it's invoked a third.

Ian Woods
 
Reply With Quote
 
Ed Morton
Guest
Posts: n/a
 
      11-10-2003


On 11/10/2003 10:13 AM, Christopher Benson-Manica wrote:
> I have a situation something like this:
>
> int foo;
>
> for( foo=bar() ; foo <= bar()+1 ; foo++ ) {
> if( !baz(foo) ) break;
> /* do stuff with foo */
> }
>
> The idea is that the loop happens at most twice - once for foo=bar(), and once
> for foo=bar()+1. If baz(foo) fails, I know I can stop. However, I don't
> think this is the "elegant" way to get this behavior - there is a break (which
> might be bad style, for some), and bar() may be called three times (which
> doesn't seem optimal). I thought of
>
> int foo=bar();
>
> do {
> if( !baz(foo) ) break;
> /* doo stuff with foo */
> } while( foo++ == bar() );
>
> , but it's no better (and is somewhat more obfuscated, to boot). Any
> thoughts?
>


If the value returned from bar() never changes, then of course you'd assign that
to a variable outside of the loop:

int foo;
int fooMin = bar();
int fooMax = fooMin + 1;

for( foo=fooMin ; foo <= fooMax ; foo++ ) {
if( !baz(foo) ) break;
/* do stuff with foo */
}

Instead of breaking out of the loop if baz() fails, the obvious change would be
to only do the work if baz() succeeds, e.g.:

int foo;
int fooMin = bar();
int fooMax = fooMin + 1;

for( foo=fooMin ; foo <= fooMax ; foo++ ) {
if( baz(foo) ) {
/* do stuff with foo */
}
}

or even:

int foo;
int fooMin = bar();
int fooMax = fooMin + 1;

for( foo=fooMin ; (foo <= fooMax) && baz(foo) ; foo++ ) {
/* do stuff with foo */
}

If the condition becomes complex, write a macro:

#define ISVALID(foo) ((foo) <= fooMax ? baz((foo)) : 0)

int foo;
int fooMin = bar();
int fooMax = fooMin + 1;

for( foo=fooMin ; ISVALID(foo) ; foo++ ) {
/* do stuff with foo */
}

Now, if bar() doesn't always return the same value, we can easily modify the
above to:

#define ISVALID(foo) ((foo) <= bar() + 1 ? baz((foo)) : 0)

int foo;

for( foo=bar() ; ISVALID(foo) ; foo++ ) {
/* do stuff with foo */
}

Regards,

Ed.

 
Reply With Quote
 
Ben Pfaff
Guest
Posts: n/a
 
      11-10-2003
Christopher Benson-Manica <(E-Mail Removed)> writes:

> int foo;
>
> for( foo=bar() ; foo <= bar()+1 ; foo++ ) {
> if( !baz(foo) ) break;
> /* do stuff with foo */
> }
>
> The idea is that the loop happens at most twice - once for foo=bar(), and once
> for foo=bar()+1. If baz(foo) fails, I know I can stop. However, I don't
> think this is the "elegant" way to get this behavior - there is a break (which
> might be bad style, for some), and bar() may be called three times (which
> doesn't seem optimal).


If I understand the situation correctly, try this:

for (foo = bar(); baz(foo) && foo <= bar() + 1; foo++) {
/* do stuff with foo */
}
--
int main(void){char p[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv wxyz.\
\n",*q="kl BIcNBFr.NKEzjwCIxNJC";int i=sizeof p/2;char *strchr();int putchar(\
);while(*q){i+=strchr(p,*q++)-p;if(i>=(int)sizeof p)i-=sizeof p-1;putchar(p[i]\
);}return 0;}
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Triple nested loop python (While loop insde of for loop inside ofwhile loop) Isaac Won Python 9 03-04-2013 10:08 AM
Getting a loop to activate a loop above it Byte Python 4 03-24-2006 03:04 AM
Condition outside loop or separate loop for different condition? - Java 12 06-15-2005 08:50 AM
while loop in a while loop Steven Java 5 03-30-2005 09:19 PM
Loop the loop... =?Utf-8?B?VGltOjouLg==?= ASP .Net 2 02-16-2005 12:21 PM



Advertisments