Reading a key inside a loop

A

Army1987

Chris Dollin said:
Richard Heathfield wrote:
while(1)
{
preamble();
if (doneCondition()) break;
postamble();
}

How 'bout:
for (preamble(); !doneCondition(); preamble())
postamble();
 
C

Chris Dollin

Richard said:
Chris Dollin said:

And the most common one of those [1] is the venerable n-and-a-half
loop:

while(1)
{
preamble();
if (doneCondition()) break;
postamble();
}

They happen often enough that I wish there were a more constrained
syntax that said that.

Yes, so do I. Nevertheless...
Now, this loop is (we hope) not infinite; does the `while(1)` trip
your abberation detectors, and what would your approach be to the
problem?

It does, because (in my very simplistic and naive view) while(1) is
making a promise that the break breaks, and I don't like breaking
promises if I can avoid it, so I would simply do this:

int done = 0;
while(!done)
{
preamble();
done = doneCondition();
if(!done)
{
postamble();
}
}

/That/ trips my abomination detector. Messing around with a new
state variable, just so that `repeat A until B do C endrepeat`,
which has an idiomatic encoding using `break` can be written
without using `while(1)` ...
Yes, it's slightly more code. I don't find this to be a big deal,
although some people obviously do. Yes, it uses an extra object. I
don't find this to be a big deal, either, although some people
obviously do. But I /do/ find it to be clearer, although some people
obviously don't.

Indeed.
 
T

Thomas Dickey

Mark McIntyre said:
On 29 Mar 2007 08:55:46 -0700, in comp.lang.c , "hstagni"
This is a FAQ. - 19.1

in this instance, the faq only suffers from mashing together too many
things into too few words...
Quick answer: you can't, C's standard IO functions all require you to
press a key to tell the programme you've finished typing.
Longer answer: your OS probably has a lower level function which can
do this. You may need to find out how to multithread your code.

well... the C language has no features for multithreading (a few
languages do). That's a topic for groups dealing with platforms
and configurations which support that.

However, multithreading is overkill, since (still in those other groups),
longstanding solutions used there frequently use the simpler polling
and time delay.
 
T

Thomas Dickey

But it'd still block for input, something the OP doesn't want. He
wants an asynchronous notification, on a key press.

This group's faq mentions nodelay(), which does what OP asked for.
(It helps to read the corresponding manpages, since the faq does
not provide enough context to understand what is meant by its advice).
 
C

Chris Dollin

Army1987 said:
How 'bout:
for (preamble(); !doneCondition(); preamble())
postamble();

Only works if the ambles will fit inside the syntax of a
`for` [I often find the preamble has a declaration and I'm
not yet ready to commit to the C99 behaviour, even though
that's what's /right/].

Also writes `preamble` twice, no biscuit.
 
A

Army1987

Chris Dollin said:
How 'bout:
for (preamble(); !doneCondition(); preamble())
postamble();

Only works if the ambles will fit inside the syntax of a
`for` [I often find the preamble has a declaration and I'm
not yet ready to commit to the C99 behaviour, even though
that's what's /right/].

Anything fits inside the syntax of a for (except declarations) if you use
commas instead of colons.
Yes, if that'd mean to use twenty-five comma operators, then it is better to
write

while (1) {
twenty_five_expressions();
if (doneCondition()) break;
lotsa_expressions();
}

but then maybe it's better to split the preamble away in a new function (but
that depends on what are you doing exactly).
 
A

Army1987

"jaysome" <[email protected]> ha scritto nel messaggio
[snip]
The more conventional form of infinite loop prefix is
for ( ; ; )

C'mon. Are we going to examine an extensive corpus of C code to find out
which is more common, or what?

Somebody said that while (1==1) can be clearer than while (1) for those who
aren't accustomed to C's concept of truth. Too bad that 1 is considered to
be true in virtually all programming languages I've ever heard of. (Also, if
that is an issue, a comment saying /*endless loop*/ would do that. And both
are clearer than for(;;), as it is not obvious to everybody what an empty
second expression in the guard of a for cycle does.)

On reading "while (1==1)" I think: Why did he bother typing three more
keystrokes? Uhm... Maybe he thinks it is clearer.
On reading "for ( ; ; ) I think: Why didn't he like while (1)? Uhm... maybe
to shut off compiler warnings. (Though I'll never understand why.)
On reading "while (1)", which is the most similar to the idiomatic way to do
that in most programming languages, I just think "Intentionally infinite
loop... where does it break? Ah, here."

But they're completely equivalent. Use whichever you want, including
float temperature_of_hell = 1.4167911e32;
while (temperature_of_hell >= 273.15)

or equivalently:

int hell_freezes_over(void)
{
float temperature_of_hell = 1.4167911e32;
float freezing_temperature = 273.15
return (temperature_of_hell < freezing_temperature);
}

while (!hell_freezes_over())
 
C

CBFalconer

jaysome said:
The more conventional form of infinite loop prefix is
for ( ; ; )

Nah. You want properly self-documenting code:

infinite_loop:
.... much incomprehensible code ....
goto infinite_loop;

post_entropy_exit:
printf("The universe has ended\n");
exit(EXIT_SUCCESS);

which is uniquely marked at both ends. You can also clearly name
all your infinite loops, which is a great help during code
reviews. Note that I have used no additional vertical space as
compared to the other proposals.
 
C

CBFalconer

Chris said:
Richard Heathfield wrote:
.... snip ...

/That/ trips my abomination detector. Messing around with a new
state variable, just so that `repeat A until B do C endrepeat`,
which has an idiomatic encoding using `break` can be written
without using `while(1)` ...

Easily deabominated by:

do {
preamble();
if (!doneCondition) postamble();
else break;
} while (1);

which puts the exiting statement right up and intimately associated
with the peculiar infinity generator.
 
C

Chris Dollin

Army1987 said:
Chris Dollin said:
while(1)
{
preamble();
if (doneCondition()) break;
postamble();
}

How 'bout:
for (preamble(); !doneCondition(); preamble())
postamble();

Only works if the ambles will fit inside the syntax of a
`for` [I often find the preamble has a declaration and I'm
not yet ready to commit to the C99 behaviour, even though
that's what's /right/].

Anything fits inside the syntax of a for (except declarations) if you use
commas instead of colons.

False.

for, while, and if are obvious examples.
 
D

Default User

Nick said:
they are funtionally identical (on any reasonable compiler).

I also use while(1) normally.
for(;;) is a particular C idiom. Perhaps a bit "clever".
Apparently for(;;) is less likely to generate a warning.


I believe some compilers do issue a warning for the while(1) form.
Also, the for(;;) version allows the "clever" macro:

#define EVER ;;

Giving one (if one is inclined towards the "clever"):

for(EVER)
{
}




Brian
 
J

Jorgen Grahn

On 30 Mar 2007 16:50:37 GMT said:
Also, the for(;;) version allows the "clever" macro:

#define EVER ;;

Giving one (if one is inclined towards the "clever"):

for(EVER)
{
}

Clever, but misleading.

for(EVER) {
/* ... */
/* nothing lasts forever */
break;
}

(Yes I know: "while" and "for" are also misleading, if taken
literally.)

/Jorgen
 
I

ilan pillemer

Richard Heathfield said:
jaysome said:



I consider "infinite loops" to be an aberration, not an idiom.

Your turn.

When I look at "Lions' Commentary on Unix 6th Edition", and I page
through the source code to Sheet 15
....and pass my eye to main()... (line 1550)
....and let my eye read the code to line 1562.. this is what I see...

for (;;) {
UISA->r[0] = 1;
if(fuibyte(0) < 0)
break;
clearseg(i);
maxmem++;
mfree(coremap, 1, i);
i++;
}

Is this an abberration? How would you write it non-abberantly?
I am new to C and would like to learn to avoid abberant coding.

Furthermore, I am learning from K&R2, as well as...
Kernighan and Pike's "The Practice of Programming",1999

On page p12 they write:

"For an infinite loop, we prefer

for(;;)
...

but

while(1)
...
is also popular. Don't use anything other than these forms"

Again, they seem to think its an idiom; and that it should be used.
 
R

Richard Heathfield

ilan pillemer said:
Richard Heathfield said:
I consider "infinite loops" to be an aberration, not an idiom.
When I look at "Lions' Commentary on Unix 6th Edition", and I page
through the source code to Sheet 15
...and pass my eye to main()... (line 1550)
...and let my eye read the code to line 1562.. this is what I see...

for (;;) {
UISA->r[0] = 1;
if(fuibyte(0) < 0)
break;
clearseg(i);
maxmem++;
mfree(coremap, 1, i);
i++;
}

Is this an abberration?

I consider it to be so, yes. It uses one C feature to defeat another.
How would you write it non-abberantly?

done = 0;
while(!done)
{
UISA->r[0] = 1;
if(!(done = fuibyte(0) < 0))
{
clearseg(i); etc etc
}
}
I am new to C and would like to learn to avoid abberant coding.

Being new to C, you should also learn that one man's aberration is
another man's feature. Opinions differ on whether broken infinite loops
are good style, and my opinion is merely that of one man.
Furthermore, I am learning from K&R2, as well as...
Kernighan and Pike's "The Practice of Programming",1999

On page p12 they write:

"For an infinite loop, we prefer

for(;;)
...

but

while(1)
...
is also popular. Don't use anything other than these forms"

Again, they seem to think its an idiom; and that it should be used.

I have to disagree with Kernighan and Pike here. I can think of only one
time where an infinite loop is a good idea, and that is the situation
where the loop is genuinely infinite (from the program's perspective).
In other words, it only stops when someone hits the big red button,
yanks out the power cord, rips out the battery, hurls the UPS out of
the window, or in some other way deprives the computer of the
continuing ability to keep the program running.

And, under those circumstances, I would select for(;;) since it avoids a
warning (e.g. "conditional expression is constant") that while(1) fails
to avoid on some compilers.
 
G

Guest

Richard said:
ilan pillemer said:
Richard Heathfield said:
I consider "infinite loops" to be an aberration, not an idiom.
When I look at "Lions' Commentary on Unix 6th Edition", and I page
through the source code to Sheet 15
...and pass my eye to main()... (line 1550)
...and let my eye read the code to line 1562.. this is what I see...

for (;;) {
UISA->r[0] = 1;
if(fuibyte(0) < 0)
break;
clearseg(i);
maxmem++;
mfree(coremap, 1, i);
i++;
}

Is this an abberration?

I consider it to be so, yes. It uses one C feature to defeat another.
How would you write it non-abberantly?

done = 0;
while(!done)
{
UISA->r[0] = 1;
if(!(done = fuibyte(0) < 0))
{
clearseg(i); etc etc
}
}

If you want to avoid infinite loops, you could also write it as

while (UISA->r[0] = 1, fuibyte(0) >= 0) {
clearseg(i);
maxmem++;
mfree(coremap, 1, i);
i++;
}

which avoids the need for a helper variable. Personally though, I
think it's easiest read simply with for(;;).
 
A

Army1987

Also, the for(;;) version allows the "clever" macro:
#define EVER ;;

And maybe
#define NEVER ;0;
(useful for example code which can't simplily being commented out because it
contains comments itself...)
 
A

ais523

Also, the for(;;) version allows the "clever" macro:




And maybe
#define NEVER ;0;
(useful for example code which can't simplily being commented out because it
contains comments itself...)

Instead of commenting out code, you can use
#if 0
/* code here */
#endif
which has the advantage of nesting.
 
A

Army1987

ais523 said:
Instead of commenting out code, you can use
#if 0
/* code here */
#endif
which has the advantage of nesting.

So does

for (;0;) {
/*code here*/
}

(Which I recognize it is not the sanest way of doing that...)
 

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
473,777
Messages
2,569,604
Members
45,234
Latest member
SkyeWeems

Latest Threads

Top