While Loop Evaluation Help

M

Marcelo De Brito

Hi!

I have been rereading K&R classical C book and rewriting my older
codes to solve its exercises.

On the exercise 1.16 is asked to print the return value of 'getchar() !
= EOF' on the standard output. I modified that problem a little bit
not to only write that value just once, but each time a character is
entered in.

The final code is this one (it works flawlessly):

#include<stdio.h>

int main()
{
int c;

printf("\nType anything and, then, press 'ENTER'.\n\n");

while( (c = (getchar() != EOF)) )
printf("The value of '(getchar() != EOF)' is %d\n", c);

printf("The value of '(getchar() != EOF)' is %d\n", c); /*
Printing zero (CTRL+D) */
return 0;
}

My question is: What is the stop condition on the
loop "while( (c = (getchar() != EOF)) )" ?

It is interesting how C accepts some unusual expressions.

Any further explanation is welcomed!

Many thanks in advance!

Marcelo!
 
G

Gene

Hi!

I have been rereading K&R classical C book and rewriting my older
codes to solve its exercises.

On the exercise 1.16 is asked to print the return value of 'getchar() !
= EOF' on the standard output. I modified that problem a little bit
not to only write that value just once, but each time a character is
entered in.

The final code is this one (it works flawlessly):

#include<stdio.h>

int main()
{
  int c;

  printf("\nType anything and, then, press 'ENTER'.\n\n");

  while( (c = (getchar() != EOF)) )
    printf("The value of '(getchar() != EOF)' is %d\n", c);

  printf("The value of '(getchar() != EOF)' is %d\n", c);      /*
Printing zero (CTRL+D) */
  return 0;

}

My question is: What is the stop condition on the
loop "while( (c = (getchar() != EOF)) )" ?

It is interesting how C accepts some unusual expressions.

Any further explanation is welcomed!

Many thanks in advance!

Marcelo!

"Stop condition" is a bit hard to understand. getchar() returns
either a character or the distinguished non-character integer value
EOF. As long as getchar() is not equal to EOF, the expression
getchar() != EOF is true. The C != operator produces a 1 in this
case, else 0 for false. This 1 or 0 is assigned to c by the =
operator. In turn, the = operator in C is an expression that has the
same value as that assigned, i.e. 0 or 1 in this case. This is the
value used to control the loop. When it's a 0, the loop fails to
execute the body's printf, and the loop terminates.
 
B

Ben Bacarisse

Marcelo De Brito said:
I have been rereading K&R classical C book and rewriting my older
codes to solve its exercises.

On the exercise 1.16 is asked to print the return value of 'getchar() !
= EOF' on the standard output. I modified that problem a little bit
not to only write that value just once, but each time a character is
entered in.
while( (c = (getchar() != EOF)) )
printf("The value of '(getchar() != EOF)' is %d\n", c);
My question is: What is the stop condition on the
loop "while( (c = (getchar() != EOF)) )" ?

The while loop executes until the controlling expression compares equal
to zero. In your example, the controlling expression is an assignment
(in C, assignment is an operator much like any other). The value of an
assignment is that of the left hand side after the assignment has taken
place. Putting this together, the loop executes until zero is assigned
to c.

Chapter 1 of K&R is a quick run-through the main features of C. I am
sure all these points are expanded on in later chapters.

<snip>
 
M

Marcelo De Brito

Hi!

Thank you so much, guys!

Initially, I had thought the "getchar() != EOF" was the statement to
get outside the while loop, but it were, indeed, a combination of both
that expression and the later assignment of its return value to "c" --
as you explained.

Thanks!

Marcelo
 
M

Marcelo De Brito

Hi!

Richard, your (and others') solutions (here: http://users.powernet.co.uk/eton/kandr2/krx1.html)
have been extremely valuable to me when I get stuck in some exercise I
can't completely solve and/or have no initial idea of how to do it.

Interesting, I did that and what I got was the ASCII number for the
given character on the input:

Type anything and, then, press 'ENTER'.

abc
The value of '(getchar() != EOF)' is 97
The value of '(getchar() != EOF)' is 98
The value of '(getchar() != EOF)' is 99
The value of '(getchar() != EOF)' is 10

The last line is the ASCII value of the newline character (ENTER/
RETURN).

By the way, thank you very much for your kind reply and for your
exercises' solutions!

Thanks!

Marcelo
 
K

Keith Thompson

Marcelo De Brito said:
My question is: What is the stop condition on the
loop "while( (c = (getchar() != EOF)) )" ?

It is interesting how C accepts some unusual expressions.
[...]

Perhaps the most unusual thing about C expressions, from the point
of view of someone more familiar with certain other languages,
is that an assignment is an expression, not a statement,
and like any expression it can appear as part of a larger expression.

In addition, there's a special kind of statement called an "expression
statement", consisting of an expression followed by a semicolon; the
expression is evaluated for its side effects and any result is quietly
discarded.

So while in, say, Pascal, this:

a := b;

is an assignment statement, the equivalent in C:

a = b;

is an expression statement where "a = b" is the expression whose
side effect is to modify a. (The result of the expression is the
value that was assigned, but as I said that's discarded.)

As you've seen, this gives you great flexibility:

a = b = c;

Since "=" is right-associative, this is equivalent to:

a = (b = c);

so it assigns the value of c to b, then assigns that same value to a.
 
T

Thad Smith

Marcelo said:
My question is: What is the stop condition on the
loop "while( (c = (getchar() != EOF)) )" ?

The stop condition is attempting to read the next character on stdin and failing
because there are no more characters. If stdin is reading a file, for example,
EOF is returned by attempting to read past the last character in the file. If
stdin is a keyboard, most systems have a way to create an EOF condition, such as
entering the control-Z character.
 
C

Chad

Marcelo De Brito said:
loop "while( (c = (getchar() != EOF)) )" ?
It is interesting how C accepts some unusual expressions.

[...]

Perhaps the most unusual thing about C expressions, from the point
of view of someone more familiar with certain other languages,
is that an assignment is an expression, not a statement,
and like any expression it can appear as part of a larger expression.

In addition, there's a special kind of statement called an "expression
statement", consisting of an expression followed by a semicolon; the
expression is evaluated for its side effects and any result is quietly
discarded.

So while in, say, Pascal, this:

    a := b;

is an assignment statement, the equivalent in C:

    a = b;

is an expression statement where "a = b" is the expression whose
side effect is to modify a.  (The result of the expression is the
value that was assigned, but as I said that's discarded.)

What in 'a' gets modified?
 
B

Ben Bacarisse

Chad said:
On Jul 22, 7:50 pm, Keith Thompson <[email protected]> wrote:

What in 'a' gets modified?

The bits. In C, the expression on the left of the assignment denotes
(or "refers to" or "means") an object -- a region of storage that can
hold bits. When a = b; is executed the value of 'b' will be converted to the
type of 'a' and the right collection of bits to represent this converted
value will be put into the object to what a refers.

A shorthand would be that a's value is modified, but objects don't hold
values in the C view of things -- they hold bits that, when interpreted
as being of some type, give rise to values.
 
K

Keith Thompson

Chad said:
What in 'a' gets modified?

Hmm? The question implies some substantial misunderstanding, but
I don't know what it might be. (Are you confusing "=", assignment,
with "==", equality comparison?)

It's an assignment; the value of b is copied into the object a,
overwriting whatever previous value it had. a is still the same object
and has the same address, but its contents are modified.

Of course it's possible that the new value is the same as the old
one; one could argue whether this counts as "modifying" it, but I
won't bother.
 
O

osmium

pete said:
It is allowed for the value of (b = c) to be assigned to (a)
before the value of (c) is assigned to (b).

[Assignment] is not a sequence point.

Words to live by! One of the most non-intuitive (to me) aspects of the
language which can - and sometimes actually does - lead to some weird
results.
 
C

Chad

Hmm?  The question implies some substantial misunderstanding, but
I don't know what it might be.  (Are you confusing "=", assignment,
with "==", equality comparison?)

It's an assignment; the value of b is copied into the object a,
overwriting whatever previous value it had.  a is still the same object
and has the same address, but its contents are modified.

Of course it's possible that the new value is the same as the old
one; one could argue whether this counts as "modifying" it, but I
won't bother.

I think some of the on going confusion stems from page 55 in second
edition of the book "The C Programming Language" by K & R. Near the
middle of the page they say:

" And expression such as x = 0 or i++ or printf(...) becomes a
statement
when it is followed by a semicolon, as in

x = 0;
i++;
printf(...);
"

Maybe I'm still not comprehending this like what I should, but you
said assignment is an expression statement. However, K & R calls it a
statement.
 
B

bart.c

I think some of the on going confusion stems from page 55 in second
edition of the book "The C Programming Language" by K & R. Near the
middle of the page they say:

" And expression such as x = 0 or i++ or printf(...) becomes a
statement
when it is followed by a semicolon, as in

x = 0;
i++;
printf(...);
"

Maybe I'm still not comprehending this like what I should, but you
said assignment is an expression statement. However, K & R calls it a
statement.

I think any expression on it's own counts as a statement:

1234;

is a statement, although the compiler might complain if it doesn't do
anything useful.
 
B

Ben Bacarisse

I think some of the on going confusion stems from page 55 in second
edition of the book "The C Programming Language" by K & R. Near the
middle of the page they say:

" And expression such as x = 0 or i++ or printf(...) becomes a
statement
when it is followed by a semicolon, as in

x = 0;
i++;
printf(...);
"

Maybe I'm still not comprehending this like what I should, but you
said assignment is an expression statement. However, K & R calls it a
statement.

There is no problem with that. A football is still a ball; a flying
fish is still a fish. Any expression can become a statement by
following it with a semicolon. If the kind of statement is important,
you call it an expression statement to distinguish it from, say, a
switch statement.
 
T

Tim Rentsch

pete said:
Keith said:
Marcelo De Brito said:
My question is: What is the stop condition on the
loop "while( (c = (getchar() != EOF)) )" ?

It is interesting how C accepts some unusual expressions.
[...]

Perhaps the most unusual thing about C expressions, from the point
of view of someone more familiar with certain other languages,
is that an assignment is an expression, not a statement,
and like any expression it can appear as part of a larger expression.

In addition, there's a special kind of statement called an "expression
statement", consisting of an expression followed by a semicolon; the
expression is evaluated for its side effects and any result is quietly
discarded.

So while in, say, Pascal, this:

a := b;

is an assignment statement, the equivalent in C:

a = b;

is an expression statement where "a = b" is the expression whose
side effect is to modify a. (The result of the expression is the
value that was assigned, but as I said that's discarded.)

As you've seen, this gives you great flexibility:

a = b = c;

Since "=" is right-associative, this is equivalent to:

a = (b = c);

so it assigns the value of c to b, then assigns that same value to a.

It is allowed for the value of (b = c) to be assigned to (a)
before the value of (c) is assigned to (b).

Assignement is not a sequence point.

The assignment to 'a' can begin (and complete) before the
storing into 'b' completes. But starting the assignment
into 'b' must occur before starting the assignment into 'a'.
 
B

Barry Schwarz

pete said:
Keith said:
[...]
My question is: What is the stop condition on the
loop "while( (c = (getchar() != EOF)) )" ?

It is interesting how C accepts some unusual expressions.
[...]

Perhaps the most unusual thing about C expressions, from the point
of view of someone more familiar with certain other languages,
is that an assignment is an expression, not a statement,
and like any expression it can appear as part of a larger expression.

In addition, there's a special kind of statement called an "expression
statement", consisting of an expression followed by a semicolon; the
expression is evaluated for its side effects and any result is quietly
discarded.

So while in, say, Pascal, this:

a := b;

is an assignment statement, the equivalent in C:

a = b;

is an expression statement where "a = b" is the expression whose
side effect is to modify a. (The result of the expression is the
value that was assigned, but as I said that's discarded.)

As you've seen, this gives you great flexibility:

a = b = c;

Since "=" is right-associative, this is equivalent to:

a = (b = c);

so it assigns the value of c to b, then assigns that same value to a.

It is allowed for the value of (b = c) to be assigned to (a)
before the value of (c) is assigned to (b).

Assignement is not a sequence point.

The assignment to 'a' can begin (and complete) before the
storing into 'b' completes. But starting the assignment
into 'b' must occur before starting the assignment into 'a'.

In the absence of any volatile qualifiers, is there a reference to
support this assertion. Under the "as if" rule, would not the
sequence
Move A to C
Move C to B
satisfy the semantics of the statement?
 
T

Tim Rentsch

Barry Schwarz said:
pete said:
Keith Thompson wrote:

[...]
My question is: What is the stop condition on the
loop "while( (c = (getchar() != EOF)) )" ?

It is interesting how C accepts some unusual expressions.
[...]

Perhaps the most unusual thing about C expressions, from the point
of view of someone more familiar with certain other languages,
is that an assignment is an expression, not a statement,
and like any expression it can appear as part of a larger expression.

In addition, there's a special kind of statement called an "expression
statement", consisting of an expression followed by a semicolon; the
expression is evaluated for its side effects and any result is quietly
discarded.

So while in, say, Pascal, this:

a := b;

is an assignment statement, the equivalent in C:

a = b;

is an expression statement where "a = b" is the expression whose
side effect is to modify a. (The result of the expression is the
value that was assigned, but as I said that's discarded.)

As you've seen, this gives you great flexibility:

a = b = c;

Since "=" is right-associative, this is equivalent to:

a = (b = c);

so it assigns the value of c to b, then assigns that same value to a.

It is allowed for the value of (b = c) to be assigned to (a)
before the value of (c) is assigned to (b).

Assignement is not a sequence point.

The assignment to 'a' can begin (and complete) before the
storing into 'b' completes. But starting the assignment
into 'b' must occur before starting the assignment into 'a'.

In the absence of any volatile qualifiers, is there a reference to
support this assertion. Under the "as if" rule, would not the
sequence
Move A to C
Move C to B
satisfy the semantics of the statement?

(Of course you meant "Move C to A" in the first step.)

First I would list these:

1. Expressions produce a value by being evaluated. Evaluating an
expression may also cause side effects, but these are consequent to
the evaluation, not before it; they may complete later, but they
can't start before. The subexpression 'b = c' doesn't produce a
value until the '=' operator is evalated, which consistutes starting
the assignment. 5.1.2.3p{2,3}, 6.5p1.

2. The value of an assignment operator "has the value of the left
operand after the assignment". In the abstract machine the
assignment must have started before the value is produced. 6.5.16p3

3. The wording in the C1X drafts is unambiguous that the value
computation for '=' of the subexpression is sequenced before
evaluating the top level '='.

4. Larry Jones has said in c.l.c (or c.s.c?) postings that the
semantics of C1X is what was intended all along for C99.

Second, to get back to your question, my earlier statement
was about the abstract machine, but your question is about
an actual machine. Logically the assignment to 'b' has to
start before the assignment to 'a', but in actual compiled
code the move instructions can be in either order, or even
not exist at all (as you say, under the "as if" rule).
However, the compiled code must behave /as if/ the assignment
to 'b' were started before the assignment to 'a', and in
particular, the address of where to store must not be
affected by the outer assignment.
 
K

Keith Thompson

Chad said:
I think some of the on going confusion stems from page 55 in second
edition of the book "The C Programming Language" by K & R. Near the
middle of the page they say:

" And expression such as x = 0 or i++ or printf(...) becomes a
statement
when it is followed by a semicolon, as in

x = 0;
i++;
printf(...);
"

Maybe I'm still not comprehending this like what I should, but you
said assignment is an expression statement. However, K & R calls it a
statement.

I don't know what you're confused about. An expression statement is
a kind of statement.
x = 0
is an assignment expression
x = 0;
is an expression statement consisting of an expression (which happens
to be an assignment expression) followed by a semicolon.

A statement expression whose expression is an assignment can
reasonably be referred to as an "assignment statement", though the
standard doesn't use that term.
 

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,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top