how to get out of double for loops?

T

Tom St Denis

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.

Usually I have code like

if ((err = blah()) != OK) goto ERROR;

So you can return "err" to the user. The only real downside is you
wouldn't know WHICH function call returned that error code. Which is
where I get more clever. In my code on GLIBC platforms when an error
occurs inside a deeper function I get a stacktrace and log it. Then
when the user dumps the error log they get a stack trace of every
error.

Most of the time that alone is sufficient to figure out the problem
without even firing up a debugger.

Tom
 
E

Eric Sosman

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

Yes (most of the time). They should have stakes driven
through their hearts -- but as has been pointed out here oft
and again, the C language itself doesn't use a stake ...
 
M

MBALOVER

Thanks a lot, guys.

This group is really helpful.

I learn a lot from your answers.

Best
 
M

Moi

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


Well, you *could* use the "cascading break" :

*************/

for (i=0; i < I; i++) {
for (j=0; j < J; j++) {
if (stuff[j] == 1) break;
}
if (j != J) break;
}

if (i != I) { found(); }
else { not_found(); }

/*************************
It is cleaner than using a flag variable; and the compiler
might optimize it away (... to a goto ...);
, but personally I find either a goto or quick return
more readable.

HTH,
AvK
 
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.


And, of course, the termination condition could be put within the
for loop, i.e.:

for(i = 0, j= 0;
(i < H) && (x[j] != 1);
(++j < H) || (j = 0, i++));


Yes, and I considered doing that. I didn't because using the
'break' form seems like a better expression of how OP
conceptualizes the problem.
To get the true spirit of C it would be better to remove all of
the spaces and put the whole thing on one line.

for(i=0,j=0;(i<H)&&(x[j]!=1);(++j<H)||(j=0,i++));

Ohnowyou'rejustbeingsilly.


[snip additional unrelated comments]
 
T

Tim Rentsch

[email protected] (Richard Harter) said:
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 :)

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;


No need to have/use an auxiliary variable y:

for( i = 0; i < H*H && ((int*)&x) != 1; i++ );

There is no end of good solutions. :)

No doubt. Now if there were just some way of getting people
to agree on which ones are the good ones... :)
 
T

Tim Rentsch

Ben Bacarisse said:
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.


Isn't it generally agreed that the Standard expects 'y = x[0]' not to
(have to) work, but 'y = (int*)x' or 'y = (int*)&x' to work? Is
there any real contention on what the Standard expects on this
particular point (even though there is debate about how well it
says it)?
 
B

Ben Bacarisse

Tim Rentsch said:
Ben Bacarisse <[email protected]> writes:
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.


Isn't it generally agreed that the Standard expects 'y = x[0]' not to
(have to) work, but 'y = (int*)x' or 'y = (int*)&x' to work? Is
there any real contention on what the Standard expects on this
particular point (even though there is debate about how well it
says it)?


I am surprised you think anything like this could be "generally
agreed" :)

I toyed with using a pointer that unambiguously referred to the whole
array (I'd have gone for (void *)x) but I did not want to invite the
debate by including a cast that some might think is not needed. I
failed of course, since here we are again.
 
T

Tim Rentsch

Ben Bacarisse said:
Tim Rentsch said:
Ben Bacarisse <[email protected]> writes:
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.


Isn't it generally agreed that the Standard expects 'y = x[0]' not to
(have to) work, but 'y = (int*)x' or 'y = (int*)&x' to work? Is
there any real contention on what the Standard expects on this
particular point (even though there is debate about how well it
says it)?


I am surprised you think anything like this could be "generally
agreed" :)


Well, I did say "generally agreed", not "universally agreed."

To be more specific, isn't it essentially universally agreed that
using '(T*)&x' will get an array for the entire region
occupied by x, even if x is a multi-dimensional array? That
assertion seems pretty uncontroversial.

I toyed with using a pointer that unambiguously referred to the whole
array (I'd have gone for (void *)x) but I did not want to invite the
debate by including a cast that some might think is not needed. I
failed of course, since here we are again.

What, you're trying to say that there is debate about whether
or not a debate exists? In comp.lang.c? Preposterous!
 
B

Ben Bacarisse

Tim Rentsch said:
Ben Bacarisse said:
Tim Rentsch said:
Ben Bacarisse <[email protected]> writes:
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.

Isn't it generally agreed that the Standard expects 'y = x[0]' not to
(have to) work, but 'y = (int*)x' or 'y = (int*)&x' to work? Is
there any real contention on what the Standard expects on this
particular point (even though there is debate about how well it
says it)?


I am surprised you think anything like this could be "generally
agreed" :)


Well, I did say "generally agreed", not "universally agreed."

To be more specific, isn't it essentially universally agreed that
using '(T*)&x' will get an array for the entire region
occupied by x, even if x is a multi-dimensional array? That
assertion seems pretty uncontroversial.


It does to me too, but I have an unsettling feeling that there was
some dissent form that view. Maybe I am misremembering.

<snip>
 
L

lawrence.jones

Eric Sosman said:
Yes (most of the time). They should have stakes driven
through their hearts -- but as has been pointed out here oft
and again, the C language itself doesn't use a stake ...

You keep making puns like that and you're going to be in a heap of
trouble.
 
N

Nick Keighley

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

can Java's break jump backwards? Can it be used outside a loop? Does
it restart execution at a named label? Because if not then Java's
break isn't goto.

C's break isn't goto either.
 
N

Nick Keighley

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.

yes. There are few places where goto is needed now (I'd be fairly
happy with a goto to solve the OPs problem).
Nowadays you
have languages like Java and C++ that provide "exceptions" which are
really the <expletive>-goto-statement-from-hell.

I seem to be spending most of my sunday morning writing "no
$CONTROL_STRUCTURE isn't a goto". Exceptions aren't gotos.

And then there was the proof that any program can be written without
using "goto" - by labelling every statement, turning all control
structures into gotos, introducing a variable holding the variable,
and ending up with a program like

int label = 1;
for (;;) {
  if (label == 1) { statement1; label = 2; }
  else if (label == 2) { statement2; label = 3; }
  else if (label == 3) { statement3; if (condition) label = 1; else
label = 4; } // That would be a simulated goto
  ...

}

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

"Bohm and Jacopini Considered Harmful"
 
N

Nick Keighley

I've not programmed in Java but if Java's exceptions are anything like
C++ then they aren't gotos (what *is* it with Java programmers? Are
they victims of Worf's hypothesis- they don't have a gotos in their
langauge therefore they can't think about them? "oh goto that's like,
er, break or throwing an exception"). C++ are strictly limited in
where they can pass control to. They can pass control out of the
current function (C gotos can't do this) they pass data. In some ways
they are like a magic function call. You don't think the "passing
data" bit is really un-goto-like?
  // statements that allocate ram/resources/etc
  if (something() !=3D OK)     { goto error; }
  if (somethingelse() !=3D 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]?

that "e" expression is the giveaway
They work much the same, but the presentation is important.  The
try/catch construction has strict limitations; the goto error
construction does not.  My view is that java is meant for
drinking and never for coding.  In some languages with exceptions
you can nest try/catch blocks and unwinding will be taken care of
automatically.  This isn't true when using gotos for error
handling.

Incidentally, how are with simulating blocks with
do {...} while (0);

In your example you could write:

   do {
      if ((result = something())     == BAD) break;
      if ((result = somethingelse()) == BAD) break;
   } while(0);
   if (result == BAD) {
      /* clean up code */
   } else {
      /* Action code */
   }
   return result;

For some reason, many people get uptight about using blocks (I'm
using the term as a block of code that is not in a loop but can
be escaped from.) Oddly enough they are have no problem with
using a function as a block.

sorry, what's a "block"? Ah you're using the while just so you use a
break? Looks a bit icky to me. I think I'd rather have gotos and be
honest about it.
How do you stand on this issue?
I'm all against backwards goto in general [that's what continue is
for].

I'm not a fan of continue. Except for empty loops.

while ((ch = getchar()) == SPACE)
continue;

 > 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].
 
Joined
Mar 7, 2010
Messages
4
Reaction score
0
MBALOVER said:
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



int main()
{
int i,j;
int arr[3][2]={5,5,1,5,5,1};
for( i=0;i<3;i++ )
{
for( j=0;j<2;j++ )
{
if( arr[j]==1 )
break;
}
if( arr[j]==1 )
break;
}
printf("arr[j] : %d\ni : %d\nj : %d\n",arr[j],i,j);

return 0;
}
you can say like this.i wish i understand your question true. does it answer your question
 
Joined
Mar 7, 2010
Messages
4
Reaction score
0
akhyls said:
int main()
{
int i,j;
int arr[3][2]={5,5,1,5,5,1};
for( i=0;i<3;i++ )
{

for( j=0;j<2;j++ )

if( arr[j]==1 )
break;

if( arr[j]==1 )
break;

printf("arr[j] : %d\ni : %d\nj : %d\n",arr[j],i,j);

return 0;
}
you can say like this.i wish i understand your question true. does it answer your question




int main()
{
**int i,j;
**int arr[3][2]={5,5,1,5,5,1};
**for( i=0;i<3;i++ )
**{
****for( j=0;j<2;j++ )
****{
******if( arr[j]==1 )
******** break;
****}
****if( arr[j]==1 )
********break;
**}
**printf("arr[j] : %d\ni : %d\nj : %d\n",arr[j],i,j);

** return 0;
}
it looks better i think:)
 
Last edited:
Joined
Mar 7, 2010
Messages
4
Reaction score
0
int main()
{
**int i,j;
**int arr[3][2]={5,5,1,5,5,1};
**for( i=0;i<3;i++ )
**{
****for( j=0;j<2;j++ )
****{
******if( arr[j]==1 )
******** break;
****}
****if( arr[j]==1 )
********break;
**}
**printf("arr[j] : %d\ni : %d\nj : %d\n",arr[j],i,j);

** return 0;
}


i think spaces are not accepted i had wanted to send like this
 
B

Ben Bacarisse

Nick Keighley said:
can Java's break jump backwards? Can it be used outside a loop? Does
it restart execution at a named label? Because if not then Java's
break isn't goto.

C's break isn't goto either.

Yes, but is that really the point that matters? break is good because it
is like a very restricted form of goto, but it is also bad because any
sort of goto has problems.

In a language (or programming style) without break and goto one can
make strong arguments about the behaviour of loops. After

while (E) { S; }

one can assert that !E is true (there may not be an "after" of
course). Banning continue and non-terminal return statements also
simplifies the reasoning about the interaction of S and E.

Some argue that the problems of carefully used gotos are mitigated by
the presence of labels that announce the potential for trouble,
whereas break silently interferes with such reasoning. Others argue
that well-used breaks can be folding into such reasoning without much
trouble. Others would say that reasoning about programs is hopeless
in C, so who cares what constructs one uses provided they get the job
done. (This are very far from an exhaustive list of views!)

I sometimes get the feeling that programmers treat this issue like
football (soccer) supporters. One team's fans are jeering "break is a
goto" and the other side is signing "break is a structured
construct"[1]. Of course there are more than two teams, but which
team one supports is less interesting than why one supports it. Maybe
we could have a bit more why when these polarising topics come up?

This is not really aimed at anyone in particular. I just picked a
place to inject a comment almost at random.

[1] These chants may need some work.
 
S

Stefan Ram

In some languages, not C of course, you can escape (break) from a
simple delimited block. If you could do this in C you could
write:
{
if ((result = something()) == BAD) break;
if ((result = somethingelse()) == BAD) break;
}

if (result == BAD) {

if
( ( result = something() ) == BAD )||
( result = somethingelse() )== BAD ))
{
 

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