how to get out of double for loops?

M

MBALOVER

Hi all,

I want to quit of both "for" loop whenever I find x[j]=1;

Do you know how to do it?

Right now, I am using the following code but I believe there should be
a much more efficient way for this task.

flag=0;
for (i=0;i<H;i++)
{
for (j=0;j<H;j++)
if (x[j]==1)
{
flag=1;
break;
}
if( flag)
break
}

Thanks
 
S

Stefan Ram

MBALOVER said:
I want to quit of both "for" loop whenever I find x[j]=1;
Do you know how to do it?


One possibility would be to put it into a function and then
use »return« (I would prefer this). Another one, »goto«. Or,
(»structured«) »i=H;j=H;«. Or, structured,

for( i = 0, iloop = 1; iloop; ++i )if( i == H )iloop = 0; else
for( j = 0, jloop = 1; jloop; ++j )if( j == H )jloop = 0; else
if( x[ i ][ j ]== 1 )iloop = jloop = 0;

Or, use Java, where »break« can take a label.
 
M

Mark Bluemel

Hi all,

I want to quit of both "for" loop whenever I find x[j]=1;

Do you know how to do it?

Right now, I am using the following code but I believe there should be
a much more efficient way for this task.

flag=0;
for (i=0;i<H;i++)
{
      for (j=0;j<H;j++)
          if (x[j]==1)
          {
               flag=1;
               break;
          }
        if( flag)
             break

}

Thanks


I doubt that efficient is really the issue here. I think elegance is
more what you are thinking of :)

As C doesn't have a labelled break (disclaimer: I haven't checked
C99), you have to do something similar to what you have.

See http://c-faq.com/misc/multibreak.html which makes a few other
suggestions.

I'd probably do a small variation on what you have here :-

found = 0;
for (i=0;i<H && !found;i++) {
for (j=0;j<H && !found;j++) {
if (x[j]==1) {
found=1;
}
}
}

Which may have some purists complaining about the inefficiency of the
repeated tests, but is to my eyes expressive and reasonably clear.
 
T

Tom St Denis

Hi all,

I want to quit of both "for" loop whenever I find x[j]=1;

Do you know how to do it?

Right now, I am using the following code but I believe there should be
a much more efficient way for this task.

flag=0;
for (i=0;i<H;i++)
{
      for (j=0;j<H;j++)
          if (x[j]==1)
          {
               flag=1;
               break;
          }
        if( flag)
             break

}


STANDBACK I'M ABOUT TO PERFORM MAGIC:

for (i=0;i<H;i++) {
for (j=0;j<H;j++) {
if (x[j] == 1) {
goto AFTER_LOOP;
}
}
}
AFTER_LOOP:
// more code here


Thanks folks!

Tom
 
M

Mark Bluemel

I want to quit of both "for" loop whenever I find x[j]=1;

Do you know how to do it?
Right now, I am using the following code but I believe there should be
a much more efficient way for this task.
flag=0;
for (i=0;i<H;i++)
{
      for (j=0;j<H;j++)
          if (x[j]==1)
          {
               flag=1;
               break;
          }
        if( flag)
             break


STANDBACK I'M ABOUT TO PERFORM MAGIC:

for (i=0;i<H;i++) {
   for (j=0;j<H;j++) {
      if (x[j] == 1) {
         goto AFTER_LOOP;
      }
   }}

AFTER_LOOP:
   // more code here


"Any references to Goto (an obscure Japanese admiral) are obscene,
unfit for your eyes and anyway don't mean what you think they do -
delete them" (notes on the Algol manual from a university course in
the 1970s).

I'm allergic to gotos - if I managed to write COBOL without goto for
many years, I think I can manage to write C without goto. (My primary
language these days is Java, which doesn't even have goto).
 
B

Ben Bacarisse

MBALOVER said:
I want to quit of both "for" loop whenever I find x[j]=1;

Do you know how to do it?

Right now, I am using the following code but I believe there should be
a much more efficient way for this task.


I am not sure, but I doubt you mean efficient. If you do, that is
whole other ball game.
flag=0;
for (i=0;i<H;i++)
{
for (j=0;j<H;j++)
if (x[j]==1)
{
flag=1;
break;
}
if( flag)
break
}


I won't repeat the good suggestions but I'll add few more to think
about. You can get rid of your flag, because what you are looking for
acts like a flag:

for (i = 0; i < H; i++) {
for (j = 0; j < H && x[j] != 1; j++);
if (j < H)
break;
}

There is no shame in using a goto here. A simple and clear jump
forward is not going to confuse anyone:

for (i = 0; i < H; i++) {
for (j = 0; j < H; j++)
if (x[j] == 1)
goto outer_break;
}
outer_break:

The trouble with gotos is the temptation! You could be drawn into
using it for more than a double break and that is the start of a
slippery slope. I would not be happy with:

for (i = 0; i < H; i++) {
for (j = 0; j < H; j++)
if (x[j] == 1)
goto found;
}
/* code here to what to do when the element is not found */
found:
/* code here for a successful search */

especially if the "not found" code is long and complex.

Finally, you could put the search in a function. This becomes, for
me, the first choice solution if you have more than one of these
loop pairs. Even with only one I'd probably use it.

The trouble with giving you an example is that there are lots of
options (what type is x? do you need C99's VLAs? do you really need
the indexes or would a pointer to the found element do?). Anyway, one
simple version might look like this:

bool find_eq1(int (*x)[H], int *rowp, int *colp)
{
for (int i = 0; i < H; i++)
for (int j = 0; j < H; j++)
if (x[j] == 1) {
*rowp = i;
*colp = j;
return true;
}
return false;
}

which you'd use like this:

if (find_eq1(x, &i, &j))
/* ... */

[This uses C99 'for' loop syntax and needs #include <stdbool.h>.]
 
R

Rob Kendrick

I'm allergic to gotos - if I managed to write COBOL without goto for
many years, I think I can manage to write C without goto. (My primary
language these days is Java, which doesn't even have goto).

What do you think break is, if not another word for goto?

B.
 
M

Mark Bluemel

What do you think break is, if not another word for goto?

I recognise that, and I'm no great fan of break (or continue).

My suggested code used neither break nor continue.
 
M

Mark Bluemel

If some article from the '70s causes you allergies, then maybe you
should seek medical help.

What makes you think my allergy comes from the article?

I've been programming in various languages for over 30 years, and I
found by experience very early on that goto was rarely useful and
could be, as the man said, harmful. I can't remember the last time I
used one.
 
N

Noob

Christian said:
That was written at a time when primitive language like BASIC and
FORTRAN 66 didn't have any decent control structures, and goto
statements had to be used to simulate control structures. Nowadays you
have languages like Java and C++ that provide "exceptions" which are
really the mother-fucking-goto-statement-from-hell.

So that makes setjmp and longjmp... what? Demonic abominations?
 
T

Tim Rentsch

MBALOVER said:
I want to quit of both "for" loop whenever I find x[j]=1;

Do you know how to do it?

Right now, I am using the following code but I believe there should be
a much more efficient way for this task.

flag=0;
for (i=0;i<H;i++)
{
for (j=0;j<H;j++)
if (x[j]==1)
{
flag=1;
break;
}
if( flag)
break
}


At some level there is really just one loop conceptually, iterating
over a square set of elements in the 2-dimensional array x. So you
might try combining the two 'for()' statements to make a single
loop, as for example:

for( i = 0, j = 0; i < H; ++j < H || (j = 0, i++) ){
if( x[j] == 1 ) break;
}

The "next value" expression is a little clunky, but that's a
byproduct of C's operator set more than anything else.
 
R

REH

I want to quit of both "for" loop whenever I find x[j]=1;

Do you know how to do it?
Right now, I am using the following code but I believe there should be
a much more efficient way for this task.
flag=0;
for (i=0;i<H;i++)
{
      for (j=0;j<H;j++)
          if (x[j]==1)
          {
               flag=1;
               break;
          }
        if( flag)
             break


STANDBACK I'M ABOUT TO PERFORM MAGIC:

for (i=0;i<H;i++) {
   for (j=0;j<H;j++) {
      if (x[j] == 1) {
         goto AFTER_LOOP;
      }
   }}

AFTER_LOOP:
   // more code here


I agree. I think the lengths people go to (no pun intended) to avoid a
simple goto statement is asinine. For a language without "named
breaks," I think this is the simplest construct. This is one of two
uses that I can think of where I find a goto as the simplest solution.
I don't believe the goto is inherently bad, but like any feature, can
be abused.

I've seen some god-awful code written because someone was allergic to
a particular programming construct (e.g., goto, do loops, break,
continue, threads, multiply inheritance, exceptions, recursive
mutexes, etc. not all are relevant to C, but you get my point). I once
saw some code written for Windows by a guy that railed against
threads. It was a mess of timer events, asynchronous I/O, and an
overly complex state machine, all to avoid creating a simple
background thread.

REH
 
T

Tom St Denis

What makes you think my allergy comes from the article?

I've been programming in various languages for over 30 years, and I
found by experience very early on that goto was rarely useful and
could be, as the man said, harmful. I can't remember the last time I
used one.

As someone pointed out exceptions in Java are really just goto,
consider the two blocks

// statements that allocate ram/resources/etc
if (something() != OK) { goto error; }
if (somethingelse() != OK) { goto error; }
// ... and so on
return OK;
error:
// clean up code
return BAD;


Then compare that to

try {
something();
somethingelse();
} catch (exception e) {
// clean up
return BAD;
}
return OK;

How are they any diff [other than presentation]? "anti-goto" rules
are fairly stupid as any strict "anti-whatever" rule kinda omits the
possibility for ... exceptions to the rule ... :)

I'm all against backwards goto in general [that's what continue is
for]. But forward goto's are perfectly fine provided they're used
when needed [exception handling and exiting a deeply nested loop being
two prime examples].

Tom
 
T

Tom St Denis

I recognise that, and I'm no great fan of break (or continue).

My suggested code used neither break nor continue.

Except that you have to add a test at every nested level which
ultimately slows it down. Why isn't a simple jump out of the loop
once you hit the particular exit condition sufficient?

Worse, your solution on exits AFTER the innermost for compound
statement is finished. What if he had

// inner loop
for (j = 0; j < H && !found; j++) {
if (x[j] == 1) { found = 1; }
x[j] += 5; // or whatever...
}


He'd now have to nest it

// inner loop
for (j = 0; j < H && !found; j++) {
if (x[j] == 1) {
found = 1;
} else {
x[j] += 5; // or whatever...
}
}

Yes, clearly that's much simpler than a simple goto out of the
nesting.

Tom
 
B

Ben Bacarisse

The trouble with gotos is the temptation! You could be drawn into
using it for more than a double break and that is the start of a
slippery slope. I would not be happy with:

for (i = 0; i < H; i++) {
for (j = 0; j < H; j++)
if (x[j] == 1)
goto found;
}
/* code here to what to do when the element is not found */
found:
/* code here for a successful search */

especially if the "not found" code is long and complex.


If my not terribly reliable understanding is correct, variables
and labels are in different name spaces so you could write:

int found = 0;
for (i = 0; i < H; i++) {
for (j = 0; j < H; j++) {
if (x[j] == 1) {
found = 1;
goto found;
}
}
}
found:
if (found) {/* found stuff */}
else {/* not found stuff */}


You could, but I don't think I'd bother. Because of the way I think
about loops, the natural test after the loop is

if (i < H) /* found what we wanted */

Another small worry I'd have is that you've labeled a position in the
source with a misleading name. OK, you only jump there when the item
is found, but I prefer to use neutral names to label location one can
simply arrive at.

<snip>
 
F

Fred

Hi all,

I want to quit of both "for" loop whenever I find x[j]=1;

Do you know how to do it?

Right now, I am using the following code but I believe there should be
a much more efficient way for this task.

flag=0;
for (i=0;i<H;i++)
{
      for (j=0;j<H;j++)
          if (x[j]==1)
          {
               flag=1;
               break;
          }
        if( flag)
             break

}


int findOne(int**x, int H, int *ip, int *jp) {
int i,j;
for (i=0;i<H;i++) {
for (j=0;j<H;j++) {
if (x[j]==1) {
*ip = i;
*jp = j;
return 1;
}
}
}
return 0;
}
 
B

Ben Bacarisse

On Fri, 05 Mar 2010 15:28:18 +0000, Ben Bacarisse

Sniff. You omitted the smiley.

I am not good with smileys. I have tried, recently, to inject a few
in to my posts but I am not entirely happy with the results :-(

As a result, I probably come over as serious and ponderous about
things that I take with a pinch of salt. Sorry if that is the case.

To keep things light and topical, here is another single loop version
to ponder the merits of:

for (i = 0; i < H*H && x[i/H][i%H] != 1; i++);

I rather like it :)
 
E

Eric Sosman

What do you think break is, if not another word for goto?

It's "break," of course.

If you equate every transfer of control with "goto," you are
confusing low-level implementation techniques with the language
structures they implement. Put it this way: If you think "break"
is "goto" (and I imagine you think of "continue" the same way),
what do you think of "return?" Of the function call operator?
Of "while" and "for" and "do" and "switch" and "if" and "else?"
Of the "?:" operator, particularly when the second and/or third
operands have side-effects? All of these cause control transfers,
sometimes more than one; are they therefore all "goto?"
 
B

Ben Bacarisse

To keep things light and topical, here is another single loop version
to ponder the merits of:

for (i = 0; i < H*H && x[i/H][i%H] != 1; i++);

I rather like it :)

And well you should. :)

You could make it more efficient (if I have the syntax right)
with

int **y; /* use appropriate type */

for (i = 0, y = (int **)x; i <HH && y != 1; i++);
j = i%H; i /= H;


I think you intended to treat x as a 1-dimensional array, yes? If so,
you wanted to write:

int *y;
for (i = 0, y = x[0]; i < H*H && y != 1; i++);
j = i%H; i /= H;

but that brings up another c.l.c FAP[1]: is indexing y from y[H]
onwards really permitted?

[1] Frequently Argued Point.
 
E

Eric Sosman

As someone pointed out exceptions in Java are really just goto,
[...]

One significant difference is that `goto' specifies the
target of the control transfer. Upon seeing `goto label' you
can hunt for `label' and know where execution will resume. But
when you see `throw new HissyFit()' all you know is that you're
going somewhere else. Where? Well, um, "it depends."

Another difference is that with `goto label', when control
arrives at `label' there's no additional information. "How did
I get here?" is unknown, unless the program is amenable to a
static analysis that reveals there's only one point of departure.
An exception carries a lot of information about its circumstances,
and that information is available to -- and manipulable by -- the
code at the `catch' point.

It seems to me that "someone" has oversimplified.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,444
Messages
2,571,709
Members
48,796
Latest member
Greg L.
Top