Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #75451 > unrolled thread
| Started by | Alla _ <modelling.data@gmail.com> |
|---|---|
| First post | 2015-11-09 06:23 -0800 |
| Last post | 2015-11-10 16:01 -0800 |
| Articles | 20 on this page of 37 — 11 participants |
Back to article view | Back to comp.lang.c
Shortened form of condition Alla _ <modelling.data@gmail.com> - 2015-11-09 06:23 -0800
Re: Shortened form of condition Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-09 14:44 +0000
Re: Shortened form of condition James Kuyper <jameskuyper@verizon.net> - 2015-11-09 10:17 -0500
Re: Shortened form of condition Barry Schwarz <schwarzb@dqel.com> - 2015-11-09 09:20 -0800
Re: Shortened form of condition Alla _ <modelling.data@gmail.com> - 2015-11-09 10:11 -0800
Re: Shortened form of condition Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-11-09 10:35 -0800
Re: Shortened form of condition Alla _ <modelling.data@gmail.com> - 2015-11-10 00:14 -0800
Re: Shortened form of condition Barry Schwarz <schwarzb@dqel.com> - 2015-11-10 03:04 -0800
Re: Shortened form of condition glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-11-10 21:42 +0000
Re: Shortened form of condition Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-10 11:13 +0000
Re: Shortened form of condition Alla _ <modelling.data@gmail.com> - 2015-11-10 07:58 -0800
Re: Shortened form of condition Richard Heathfield <rjh@cpax.org.uk> - 2015-11-10 17:06 +0000
Re: Shortened form of condition James Kuyper <jameskuyper@verizon.net> - 2015-11-10 12:11 -0500
Re: Shortened form of condition James Kuyper <jameskuyper@verizon.net> - 2015-11-10 14:01 -0500
Re: Shortened form of condition Keith Thompson <kst-u@mib.org> - 2015-11-10 08:30 -0800
Re: Shortened form of condition Alla _ <modelling.data@gmail.com> - 2015-11-10 09:07 -0800
Re: Shortened form of condition Keith Thompson <kst-u@mib.org> - 2015-11-10 09:29 -0800
Re: Shortened form of condition Alla _ <modelling.data@gmail.com> - 2015-11-10 11:02 -0800
Re: Shortened form of condition Keith Thompson <kst-u@mib.org> - 2015-11-10 11:33 -0800
Re: Shortened form of condition Alla _ <modelling.data@gmail.com> - 2015-11-11 00:28 -0800
Re: Shortened form of condition Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-11 16:05 +0000
Re: Shortened form of condition glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-11-12 09:29 +0000
Re: Shortened form of condition Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-12 10:56 +0000
Re: Shortened form of condition Richard Heathfield <rjh@cpax.org.uk> - 2015-11-11 16:24 +0000
Re: Shortened form of condition Keith Thompson <kst-u@mib.org> - 2015-11-11 08:53 -0800
Re: Shortened form of condition Richard Heathfield <rjh@cpax.org.uk> - 2015-11-11 16:59 +0000
Re: Shortened form of condition Alla _ <modelling.data@gmail.com> - 2015-11-11 06:42 -0800
Re: Shortened form of condition Eric Sosman <esosman@comcast-dot-net.invalid> - 2015-11-10 14:04 -0500
Re: Shortened form of condition Barry Schwarz <schwarzb@dqel.com> - 2015-11-10 10:43 -0800
Re: Shortened form of condition James Kuyper <jameskuyper@verizon.net> - 2015-11-09 13:44 -0500
Re: Shortened form of condition Keith Thompson <kst-u@mib.org> - 2015-11-09 10:57 -0800
Re: Shortened form of condition Philip Lantz <prl@canterey.us> - 2015-11-10 01:52 -0800
Re: Shortened form of condition Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-09 19:35 +0000
Re: Shortened form of condition Keith Thompson <kst-u@mib.org> - 2015-11-09 11:52 -0800
Re: Shortened form of condition Alla _ <modelling.data@gmail.com> - 2015-11-10 00:33 -0800
Re: Shortened condition Richard Heathfield <rjh@cpax.org.uk> - 2015-11-10 09:00 +0000
Re: Shortened form of condition Tim Rentsch <txr@alumni.caltech.edu> - 2015-11-10 16:01 -0800
Page 1 of 2 [1] 2 Next page →
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2015-11-09 06:23 -0800 |
| Subject | Shortened form of condition |
| Message-ID | <b6b2a9ec-4944-4e34-95e1-779161509469@googlegroups.com> |
Hello!
I already have a post on almost the same issue, therefore I apologize
for repeating it. I do so because the issue haunts me, although last time
I was sure it is solved (I have many times written and re-written it on
paper, worked perfectly).
Here is the main function of the program that counts words in a text:
int main (void)
{
char text[81];
int total_words = 0;
bool end_of_text = false;
printf ("Type in your text.\n");
printf ("When done, press 'RETURN'.\n\n");
while ( !end_of_text )
{
read_line (text);
if (text[0] == '\0')
end_of_text = true;
else
total_words += count_words (text);
}
printf ("\nThere are %i words in the above text.\n", total_words);
return 0;
}
I have an issue with the shorted form of condition in while statement.
Before the loop starts the bool value end_of_text is set to
false.
Read_line() function reads the input until the user enters '\n'
(I am not posting this function here, because it is not relevant
to my question).
The condition in the loop says: while (not end_of_text);
end_of_text was set to false initially, hence I assume 'not end_of_text'
means that 'while end_of_text is true', which (I understand it) is logically incorrect. I don't see how while loop works - why and when it starts and ends.
I fully understand only the if else part:
End_of_text becomes true only within while loop, if the first element of text
equals null terminating character, which means that no text has been entered,
only '\n'. If text has been entered, then the function that counts words
is called.
Thank you!
[toc] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-11-09 14:44 +0000 |
| Message-ID | <87h9kvp6zb.fsf@bsb.me.uk> |
| In reply to | #75451 |
Alla _ <modelling.data@gmail.com> writes:
> int main (void)
> {
<snip>
> bool end_of_text = false;
<snip>
> while ( !end_of_text )
> {
<snip>
> }
<snip>
> }
> I have an issue with the shorted form of condition in while statement.
>
> Before the loop starts the bool value end_of_text is set to
> false.
<snip>
> The condition in the loop says: while (not end_of_text);
>
> end_of_text was set to false initially, hence I assume 'not
> end_of_text' means that 'while end_of_text is true',
You need to break it down into parts -- there's the while statement and
the controlling expression and you need to treat them separately. You
don't want to if "while ..." is true. What matters is the value of the
expression, and the loop will execute provided that expression is 'true'.
The fact that (initially) end_of_text is false simply means that
!end_of_text is true. In fact 'false', in C, is just another word for 0
and !end_of_text will have the value 1. Another ! would flip the value
again making !!end_of_text 0. Just to be sure, try it:
#include <stdio.h>
#include <stdbool.h>
int main(void)
{
bool end_of_text = false;
printf("eot=%d !eot=%d !!eot=%d\n",
end_of_text, !end_of_text, !!end_of_text);
}
> which (I understand it) is logically incorrect. I don't see how while loop
> works - why and when it starts and ends.
So when the loop is first encountered, the controlling expression has
the value 1 -- that's 'true' in C speak, so the body of the loop will be
entered. Any time the body of the loop sets end_of_text to true (1),
the next time the controlling expression -- !end_of_text -- is evaluated
the result will be false (0) and the body won't be entered.
<snip>
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2015-11-09 10:17 -0500 |
| Message-ID | <n1qdan$sg$1@dont-email.me> |
| In reply to | #75451 |
On 11/09/2015 09:23 AM, Alla _ wrote:
...
> bool end_of_text = false;
>
> printf ("Type in your text.\n");
> printf ("When done, press 'RETURN'.\n\n");
>
> while ( !end_of_text )
> {
> read_line (text);
>
> if (text[0] == '\0')
> end_of_text = true;
>
> else
> total_words += count_words (text);
> }
>
...
> I have an issue with the shorted form of condition in while statement.
>
> Before the loop starts the bool value end_of_text is set to
> false.
>
> Read_line() function reads the input until the user enters '\n'
> (I am not posting this function here, because it is not relevant
> to my question).
>
> The condition in the loop says: while (not end_of_text);
>
> end_of_text was set to false initially, hence I assume 'not end_of_text'
> means that 'while end_of_text is true',
Ben has already answered this question, and his answer is correct, but
I'll use a slightly different approach to giving you the same answer:
In C , true is 1 and false is 0, and all C operators that return logical
results return one of those values. In those contexts where C evaluates
a condition, 0 is treated as false, and non-zero is treated as true.
Therefore, while(condition) should be read in English as "while
condition compares unequal to 0". This particular statement could be
read as "while 'not end_of_text' compares unequal to 0". If end_of_text
is false, then "not end_of_text" is true, and therefore compares unequal
to zero; if end_of_text is true, then "not end_of_text" is false, which
compares equal to 0. Therefore, this is equivalent to saying "while
end_of_text is false".
> which (I understand it) is logically incorrect. I don't see how while loop works - why and when it starts and ends.
Setting end_of_text to false ensures that the condition of the while is
true, thereby executing the body of the loop. It continues looping until
the line "end_of_text = true;" is executed, in which case "not
end_of_text" will be false, so the loop ends.
--
James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | Barry Schwarz <schwarzb@dqel.com> |
|---|---|
| Date | 2015-11-09 09:20 -0800 |
| Message-ID | <qjj14bh8e378ks9hc7omk4fk899iejtib1@4ax.com> |
| In reply to | #75451 |
On Mon, 9 Nov 2015 06:23:22 -0800 (PST), Alla _
<modelling.data@gmail.com> wrote:
>Hello!
>
>I already have a post on almost the same issue, therefore I apologize
>for repeating it. I do so because the issue haunts me, although last time
>I was sure it is solved (I have many times written and re-written it on
>paper, worked perfectly).
>
>Here is the main function of the program that counts words in a text:
>
>int main (void)
>{
> char text[81];
> int total_words = 0;
> bool end_of_text = false;
>
> printf ("Type in your text.\n");
> printf ("When done, press 'RETURN'.\n\n");
>
> while ( !end_of_text )
> {
> read_line (text);
>
> if (text[0] == '\0')
> end_of_text = true;
>
> else
> total_words += count_words (text);
> }
>
> printf ("\nThere are %i words in the above text.\n", total_words);
>
> return 0;
>
>}
>I have an issue with the shorted form of condition in while statement.
>
>Before the loop starts the bool value end_of_text is set to
>false.
>
>Read_line() function reads the input until the user enters '\n'
>(I am not posting this function here, because it is not relevant
>to my question).
>
>The condition in the loop says: while (not end_of_text);
Details like punctuation are important. If your code had actually
included that semicolon you while loop would have been empty and run
forever.
>end_of_text was set to false initially, hence I assume 'not end_of_text'
>means that 'while end_of_text is true', which (I understand it) is logically incorrect.
Yes, your assumption is wrong. The expression end_of_text evaluates
to true only when the variable end_of_text has a non-zero value. The
! operator inverts the value of a logical expression. Therefore, the
expression !end_of_text evaluates to false when the variable
end_of_text has a non-zero value. It follows that this expression
evaluates to true when end_of_text has a value of zero.
Since zero is treated as false in logical expressions, you can
interpret your while statement as "loop as long as end_of_text is
false." Since the variable is initialized to false, you are
guaranteed at least one iteration. Within each iteration, you decide
whether to change the variable. When you finally do change the
variable, that interpretation no longer describes the state of the
variable and the program exits the loop.
>I don't see how while loop works - why and when it starts and ends.
All loops are controlled by an iteration statement. Each iteration
statement specifies a "controlling expression." For the while
statement, the controlling expression is evaluated prior to each
iteration. The loop body is executed repeatedly until the controlling
expression evaluates to 0 (false). The condition of your controlling
expression is described above.
--
Remove del for email
[toc] | [prev] | [next] | [standalone]
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2015-11-09 10:11 -0800 |
| Message-ID | <62775b24-22c8-4b78-85ca-6ca99456f2c5@googlegroups.com> |
| In reply to | #75451 |
Thank you for your explanations. I am sorry but Ben and James suggested the ones that are close to my interpretation, while Barry has a different one. I don't have problems with reading bool values and their opposites, but I do have an issue with controlling expressions and the way bool values are used in them. 1) Ben and James suggest (it is close to how I have read the condition of while loop), if I am not mistaken, that because end_of_text had been initially set to false, i.e. to 0, then "while (!end_of_text)" means "while(end_of_text is true, i.e. equals 1)". Hence, when the loop is first encountered, the controlling expression of end_of_text is 1 (!end_of_text). The loop iterates while this controlling expression is equal to 1. But in case the inner if condition is met, which sets end_of_text to true, i.e. to 1, the next round of while loop will be terminated because now !end_of_text will be equal to false. If this is the correct reading, then does it mean that I give the while loop a peremptory value of end_of_text being True (opposite to the initial value), and the while loop takes it for granted, because nothing has physically occurred that would change initial assignment of 0 value to end_of_text? 2) Barry suggests a different approach. while(!end_of_text) means that end_of_text is false, i.e. as it had been initially declared. Hence the loop iterates if this condition holds; it ends terminates only if the inner if conditions is met and the value of end_of_text is set to true. Therefore, which version is a correct one? :) And also, in either of above interpretations, - how does this while loop know when to stop looping, if the inner if condition is not met, if there is a text to read?
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2015-11-09 10:35 -0800 |
| Message-ID | <b00e933e-a728-4daa-a36a-0ac6a929991d@googlegroups.com> |
| In reply to | #75473 |
On Monday, November 9, 2015 at 6:11:49 PM UTC, Alla _ wrote:
>
> If this is the correct reading, then does it mean that I give the while loop
> a peremptory value of end_of_text being True (opposite to the initial value),
> and the while loop takes it for granted, because nothing has physically occurred
> that would change initial assignment of 0 value to end_of_text?
>
> 2) Barry suggests a different approach. while(!end_of_text) means that
> end_of_text is false, i.e. as it had been initially declared. Hence the loop
> iterates if this condition holds; it ends terminates only if the inner if
> conditions is met and the value of end_of_text is set to true.
>
> Therefore,
> which version is a correct one? :)
>
> And also, in either of above interpretations, - how does this while loop
> know when to stop looping, if the inner if condition is not met, if there
> is a text to read?
>
I'd expect a variable called "end_of_text" to take the value 0, or false,
whilst there is s till text to process, and the value 1, or at least non-zero,
when the text has run out.
A C while loop reads the condition on every pass.
So if we write
int end_of_text = 0;
while(end_of_text == 0)
{
int ch = fgetc(stdin);
if(ch == EOF)
end_of_text = 1;
else
fputc(stdout, ch);
}
the function will loop until the condition ch == EOF is
true. Then end_of_text goes to 1, and the loop stops.
C allows a shortcut form,
while(!end_of_text), or while not end_of_text. Whether to
use it or not is just a small style point. However you do need
the !, or not, to build up complicated conditions.
[toc] | [prev] | [next] | [standalone]
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2015-11-10 00:14 -0800 |
| Message-ID | <3093d138-02fd-4830-82b5-97feec5148e9@googlegroups.com> |
| In reply to | #75481 |
On Monday, November 9, 2015 at 10:35:41 PM UTC+4, Malcolm McLean wrote:
> On Monday, November 9, 2015 at 6:11:49 PM UTC, Alla _ wrote:
> >
> > If this is the correct reading, then does it mean that I give the while loop
> > a peremptory value of end_of_text being True (opposite to the initial value),
> > and the while loop takes it for granted, because nothing has physically occurred
> > that would change initial assignment of 0 value to end_of_text?
> >
> > 2) Barry suggests a different approach. while(!end_of_text) means that
> > end_of_text is false, i.e. as it had been initially declared. Hence the loop
> > iterates if this condition holds; it ends terminates only if the inner if
> > conditions is met and the value of end_of_text is set to true.
> >
> > Therefore,
> > which version is a correct one? :)
> >
> > And also, in either of above interpretations, - how does this while loop
> > know when to stop looping, if the inner if condition is not met, if there
> > is a text to read?
> >
>
> I'd expect a variable called "end_of_text" to take the value 0, or false,
> whilst there is s till text to process, and the value 1, or at least non-zero,
> when the text has run out.
>
> A C while loop reads the condition on every pass.
>
> So if we write
>
> int end_of_text = 0;
>
> while(end_of_text == 0)
> {
> int ch = fgetc(stdin);
> if(ch == EOF)
> end_of_text = 1;
> else
> fputc(stdout, ch);
> }
>
> the function will loop until the condition ch == EOF is
> true. Then end_of_text goes to 1, and the loop stops.
Exactly. This what I was thinking about, but in that program
the author doesn't have EOF condition that turns end_of_text
to true, but the condition when the user has not entered any
text at all, i.e. text[0] = '\0'. This what confuses me.
It would be clear had they offered the EOF condition.
Given they didn't, I don't see why the loop should ever
terminate.
[toc] | [prev] | [next] | [standalone]
| From | Barry Schwarz <schwarzb@dqel.com> |
|---|---|
| Date | 2015-11-10 03:04 -0800 |
| Message-ID | <7ij34b98dpo7rmj7prrd5m974psgmgekjn@4ax.com> |
| In reply to | #75554 |
On Tue, 10 Nov 2015 00:14:34 -0800 (PST), Alla _ <modelling.data@gmail.com> wrote: >Exactly. This what I was thinking about, but in that program >the author doesn't have EOF condition that turns end_of_text >to true, but the condition when the user has not entered any >text at all, i.e. text[0] = '\0'. This what confuses me. >It would be clear had they offered the EOF condition. >Given they didn't, I don't see why the loop should ever >terminate. Entering EOF from the keyboard is system specific and not well known to non-programmer users. I know how to do it on Windows and Unix but even as a system programmer I don't remember how to do it on an IBM mainframe. Entering an empty line by pressing Enter without typing any other data is easier, portable, and much more popular. -- Remove del for email
[toc] | [prev] | [next] | [standalone]
| From | glen herrmannsfeldt <gah@ugcs.caltech.edu> |
|---|---|
| Date | 2015-11-10 21:42 +0000 |
| Message-ID | <n1tobq$rp8$1@speranza.aioe.org> |
| In reply to | #75567 |
Barry Schwarz <schwarzb@dqel.com> wrote: (snip) > Entering EOF from the keyboard is system specific and not well known > to non-programmer users. I know how to do it on Windows and Unix but > even as a system programmer I don't remember how to do it on an IBM > mainframe. Entering an empty line by pressing Enter without typing > any other data is easier, portable, and much more popular. Not completely obvious, but the closest I knew on any IBM mainframes uses ATTN on the 2741, or BREAK on ASCII terminals. That is, an out of band EOF indicator. I don't know why unix didn't go for BREAK. -- glen
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-11-10 11:13 +0000 |
| Message-ID | <87k2pqm7jw.fsf@bsb.me.uk> |
| In reply to | #75554 |
Alla _ <modelling.data@gmail.com> writes:
<snip>
> Exactly. This what I was thinking about, but in that program
> the author doesn't have EOF condition that turns end_of_text
> to true, but the condition when the user has not entered any
> text at all, i.e. text[0] = '\0'. This what confuses me.
> It would be clear had they offered the EOF condition.
> Given they didn't, I don't see why the loop should ever
> terminate.
This is a very interesting remark, though I'm not sure how to help
dislodge you from this misunderstanding. You are saying that this is
clear:
while (end_of_text == 0)
{
int ch = fgetc(stdin);
if (ch == EOF)
end_of_text = 1;
else /* do something with the data */
}
but this
while (end_of_text == 0)
{
read_line(text)
if (text[0] == '\0')
end_of_text = 1;
else /* do something with the data */
}
is not. Mainly, it seems, because the first refers to EOF. Most
experienced programmer will see these two as slight variation of the
same pattern. So what about this one that is half way between the two?
while (end_of_text == 0)
{
int ch = fgetc(stdin);
if (ch == 'q')
end_of_text = 1;
else /* do something with the data */
}
What does it do?
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2015-11-10 07:58 -0800 |
| Message-ID | <68f30be3-232d-4e2a-8630-b2a60d2f51d6@googlegroups.com> |
| In reply to | #75569 |
<snip>
> while (end_of_text == 0)
> {
> int ch = fgetc(stdin);
> if (ch == EOF)
> end_of_text = 1;
> else /* do something with the data */
> }
>
> but this
>
> while (end_of_text == 0)
> {
> read_line(text)
> if (text[0] == '\0')
> end_of_text = 1;
> else /* do something with the data */
> }
>
> is not. Mainly, it seems, because the first refers to EOF. Most
> experienced programmer will see these two as slight variation of the
> same pattern. So what about this one that is half way between the two?
>
> while (end_of_text == 0)
> {
> int ch = fgetc(stdin);
> if (ch == 'q')
> end_of_text = 1;
> else /* do something with the data */
> }
>
> What does it do?
>
Below is a more detailed description of my question. But answering your
question and commenting on your example with EOF: yes, it is clear comparing
to the version I have in a program. With EOF condition the value of end_of_text
changes to 1 (or TRUE) when the program has reached the end of the text (past
the end of input), and hence the loop terminates - no more text to read.
if (ch == 'q')
> end_of_text = 1;
This one is close to the one I have in a program: the end_of_text is set to
1 when the character 'q' is read in.
>
My question has 2 parts:
1) the one about how end_of_text ever changes its value (below this question
in more details)
2) when and how the loop ever terminates (apart from only one condition when
the user has not entered anything at all)
Now I will do my best, well, my poor, humble best, to explain what I
don't understand.
Before let me say that I do hope I clearly understand the meaning of the
while loop in general and the "!" operand - these guys has not previously
caused any problems to me.
<snip>
/** Initially the value of end_of_text is set to false, or 0 **/
bool end_of_text = false;
/** the while loop has a condition of "end_of_text != 0", i.e. end_of_text
should be TRUE, or any non-zero value ( the value that is different from the one
it was set to initially, it has to be non-false), for the loop to start **/
/** I understand it as follows: if some particular variable has been initially
assigned a certain value, and after that the variable is used within a loop with a condition that negates that initial value, then the value in a
condition should be opposite to the initial value:
for example
int y = 2;
while (!y)
...
means that y should be 2, it is set to 2; and only if and while it is not
equal to 2, the loop does something. **/
/** On the other hand is sounds illogical for the variable with a name
end_of_text to be set to True to start a while loop in order to read in the text from the user **/
while ( !end_of_text )
{
/** If what is said above is correct, then how does the program change the
value of end_of_text to the one opposite to the initial value of 0 (or false)
for the while loop to start its action?
The loop can't start unless it spots the value of end_of_text being different
from initial value of 0. Where and how is that value being changed for the
while loop to start at least for the first time?
If there were no initial end_of_text = 0, then the whole while loop story
would look much more clear:
while (!end_of_text) (same as while end_of_text is false)
read input text
but if the user has not entered any text if (text[0] == '\0')
set the value of end_of_text to True and terminate the loop
2) If there is only one condition for the end_of_text to change its
value, and that is when the user has not entered any text, than why the
loop ever stops if the user has entered text?
One more time my interpretation of that piece:
- set bool variable end_of_text to false (to 0)
- while the variable end_of_text is not equal to 0 (while it is TRUE)
- read the string from the user
- but if the user has not entered any text (text[0] == '\0')
set the value of end_of_text to 1; in this case the loop
will evaluate the value the end_of_text as not answering its
condition of end_of_text being anything but false; because
not !end_of_text will actually equal to end_of_text != 1, i.e.
equal 0.
- and I don't see any other condition for the while loop to terminate
I hope that this verbiage is not too distracting. I did my best to explain
the welter of thoughts produced in me by this tiny piece of code.
Thank you!
[toc] | [prev] | [next] | [standalone]
| From | Richard Heathfield <rjh@cpax.org.uk> |
|---|---|
| Date | 2015-11-10 17:06 +0000 |
| Message-ID | <n1t82m$321$1@dont-email.me> |
| In reply to | #75589 |
On 10/11/15 15:58, Alla _ wrote:
<snip>
> My question has 2 parts:
> 1) the one about how end_of_text ever changes its value (below this question
> in more details)
When you tell it to. (Below, this answer in more detail.)
> 2) when and how the loop ever terminates (apart from only one condition when
> the user has not entered anything at all)
When you tell it to.
>
> Now I will do my best, well, my poor, humble best, to explain what I
> don't understand.
>
> Before let me say that I do hope I clearly understand the meaning of the
> while loop in general and the "!" operand - these guys has not previously
> caused any problems to me.
I'm not sure that that's true, for reasons which will become apparent below.
>
> <snip>
>
> /** Initially the value of end_of_text is set to false, or 0 **/
>
> bool end_of_text = false;
Well, let's stick with 0 for now. "true" and "false" may be muddying the
waters somewhat.
>
> /** the while loop has a condition of "end_of_text != 0", i.e. end_of_text
> should be TRUE, or any non-zero value
Right.
> ( the value that is different from the one
> it was set to initially, it has to be non-false), for the loop to start **/
Right.
> /** I understand it as follows: if some particular variable has been initially
> assigned a certain value, and after that the variable is used within a loop with a condition that negates that initial value, then the value in a
> condition should be opposite to the initial value:
The truth value (either 0 or non-0) should be opposite, yes.
>
> for example
> int y = 2;
> while (!y)
> ...
>
> means that y should be 2, it is set to 2; and only if and while it is not
> equal to 2, the loop does something. **/
No, not even remotely right.
int y = 2;
means "define an object of type int, call it y, and set its value to 2"
while(!y)
means "for as long as !y continues to be non-zero" which, put another
way, is "for as long as y continues to be zero". Since y isn't zero
(because it's 2), the loop never even starts!
> /** On the other hand is sounds illogical for the variable with a name
> end_of_text to be set to True to start a while loop in order to read in the text from the user **/
Right, so you don't set it to true. You set it to false (that is, 0).
And then you loop while it *continues* to be 0.
As soon as it's set to 1 (to indicate "end of text has now happened"),
we are no longer in the state "NOT end of text", because we have moved
into a state such that "end of text" is true, and thus the state "NOT
end of text" must now be FALSE, and that's what stops the loop.
> while ( !end_of_text )
> {
> /** If what is said above is correct, then how does the program change the
> value of end_of_text to the one opposite to the initial value of 0 (or false)
> for the while loop to start its action?
No.
end_of_text is 0 at the beginning because we're NOT at the end of text.
NOT 0 is 1, and NOT 1 (or indeed NOT any non-zero value) is 0.
The loop can only start BECAUSE end_of_text is 0.
If end_of_text were 1, !end_of_text (NOT end_of_text) would evaluate to
0, so the while loop would be while(0) and wouldn't get started.
Because end_of_text is 0, !end_of_text (that is, NOT end_of_text) is 1,
and so the while loop is while(1) (for now), and thus *can* get started.
> The loop can't start unless it spots the value of end_of_text being different
> from initial value of 0.
No, it can only start *because* end_of_text's initial value is 0,
because it isn't testing the value of end_of_text, it's testing the
value of !end_of_text (NOT end_of_text).
Try looking at it this way:
REACHED_DESTINATION = 0
WHILE(NOT REACHED_DESTINATION)
{
DRIVE_ALONG_THE_ROAD
IF(WE ARE THERE)
{
REACHED_DESTINATION = 1
}
}
Does that help?
> Where and how is that value being changed for the
> while loop to start at least for the first time?
>
> If there were no initial end_of_text = 0, then the whole while loop story
> would look much more clear:
>
> while (!end_of_text) (same as while end_of_text is false)
Unless end_of_text is set to 0, the above line Just Won't Work. The loop
would never get started.
> One more time my interpretation of that piece:
>
> - set bool variable end_of_text to false (to 0)
>
> - while the variable end_of_text is not equal to 0 (while it is TRUE)
No no no. While the *****expression***** "NOT end_of_text" is not equal
to 0.
There is all the difference in the world between
while(end_of_text)
and
while(!end_of_text)
--
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2015-11-10 12:11 -0500 |
| Message-ID | <n1t8cm$4fr$1@dont-email.me> |
| In reply to | #75589 |
On 11/10/2015 10:58 AM, Alla _ wrote:
> <snip>
>> while (end_of_text == 0)
>> {
>> int ch = fgetc(stdin);
>> if (ch == EOF)
>> end_of_text = 1;
>> else /* do something with the data */
>> }
>>
>> but this
>>
>> while (end_of_text == 0)
>> {
>> read_line(text)
>> if (text[0] == '\0')
>> end_of_text = 1;
>> else /* do something with the data */
>> }
>>
>> is not. Mainly, it seems, because the first refers to EOF. Most
>> experienced programmer will see these two as slight variation of the
>> same pattern. So what about this one that is half way between the two?
>>
>> while (end_of_text == 0)
>> {
>> int ch = fgetc(stdin);
>> if (ch == 'q')
>> end_of_text = 1;
>> else /* do something with the data */
>> }
>>
>> What does it do?
>>
> Below is a more detailed description of my question. But answering your
> question and commenting on your example with EOF: yes, it is clear comparing
> to the version I have in a program. With EOF condition the value of end_of_text
> changes to 1 (or TRUE) when the program has reached the end of the text (past
> the end of input), and hence the loop terminates - no more text to read.
>
> if (ch == 'q')
>> end_of_text = 1;
> This one is close to the one I have in a program: the end_of_text is set to
> 1 when the character 'q' is read in.
>>
>
> My question has 2 parts:
> 1) the one about how end_of_text ever changes its value (below this question
> in more details)
> 2) when and how the loop ever terminates (apart from only one condition when
> the user has not entered anything at all)
>
> Now I will do my best, well, my poor, humble best, to explain what I
> don't understand.
>
> Before let me say that I do hope I clearly understand the meaning of the
> while loop in general and the "!" operand - these guys has not previously
> caused any problems to me.
>
> <snip>
>
> /** Initially the value of end_of_text is set to false, or 0 **/
>
> bool end_of_text = false;
>
> /** the while loop has a condition of "end_of_text != 0", i.e. end_of_text
> should be TRUE, or any non-zero value ( the value that is different from the one
> it was set to initially, it has to be non-false), for the loop to start **/
That's dead wrong, and you've been told that it's wrong multiple times
by many different people.
while(!end_of_text) tests whether !end_of_text is != 0. If end_of_text
is true (==1), then !end_of_text is false (==0). Therefore, the loop
would not be entered if end_of_text is true.
That's why end_of_text is actually initialized to false. !end_of_text is
therefore 1 (==true), which compares unequal to 0, and as a result the
loop is, in fact, entered.
> /** I understand it as follows: if some particular variable has been initially
> assigned a certain value, and after that the variable is used within
> a loop with a condition that negates that initial value, then the value in a
> condition should be opposite to the initial value:
>
> for example
> int y = 2;
> while (!y)
> ...
> means that y should be 2, it is set to 2; and only if and while it is not
> equal to 2, the loop does something. **/
That has nothing to do with reality. The expression !y has a value of 0
if y is non-zero, and a value 1 if y is 0. while(!y) executes the body
of the loop only if !y is non-zero. That only happens when y is 0. y=2
would cause the loop to not be entered.
I don't understand what it is that you're misunderstanding about while()
loops, but it's something pretty major. We've all repeatedly tried to
explain to you how they work, and you keep coming up with nonsense like
this which suggests that you haven't understood a word that we've said
about the matter. It's very frustrating.
> /** On the other hand is sounds illogical for the variable with a name
> end_of_text to be set to True to start a while loop in order to read in the text from the user **/
It's logical to set "end_of_text" to be false, because processing has
not yet reached the end of the text. When processing does reach the end
of the text, that's when you should set end_of_text to true - and that
is, indeed, precisely what this code does.
> while ( !end_of_text )
> {
> /** If what is said above is correct, then how does the program change the
> value of end_of_text to the one opposite to the initial value of 0 (or false)
> for the while loop to start its action?
No such change occurs, which is good, since what you said above is
exactly opposite of the truth. Therefore, no change in value is needed.
> The loop can't start unless it spots the value of end_of_text being different
> from initial value of 0.
False - it can only start if the end_of_text keeps it's initial value of 0.
> ... Where and how is that value being changed for the
> while loop to start at least for the first time?
It isn't changed, which is precisely what allows the loop to start for
the first time.
> If there were no initial end_of_text = 0, then the whole while loop story
> would look much more clear:
If there were no initial end_of_text=0, then end_of_text would have an
indeterminate value. As a result, you couldn't be sure whether
!end_of_text were 0 or 1. As a result, you couldn't be sure whether the
loop would or would not be entered. This is not a desirable state of
affairs.
Note that bool is allowed to have trap representations. It's entirely
plausible than an implementation might define any bit pattern for a bool
object other than those that represent 0 or 1 to be trap
representations. If the value of a bool object is indeterminate, one of
the possibilities allowed by the standard is that it might contain a
trap representation. Any attempt to read the value of an object
containing a trap representation has undefined behavior. DON'T DO THIS!
> while (!end_of_text) (same as while end_of_text is false)
> read input text
> but if the user has not entered any text if (text[0] == '\0')
> set the value of end_of_text to True and terminate the loop
>
> 2) If there is only one condition for the end_of_text to change its
> value, and that is when the user has not entered any text, than why the
> loop ever stops if the user has entered text?
Because each pass through the loop gives the user a fresh chance to
enter text. The loop ends when the user decides not to enter any more text.
> One more time my interpretation of that piece:
>
> - set bool variable end_of_text to false (to 0)
Correct.
> - while the variable end_of_text is not equal to 0 (while it is TRUE)
Exactly the opposite of the truth. Are you ignoring the "!" operator?
But you said that you understood that operator?
> - read the string from the user
Correct.
> - but if the user has not entered any text (text[0] == '\0')
> set the value of end_of_text to 1; in this case the loop
> will evaluate the value the end_of_text as not answering its
> condition of end_of_text being anything but false; because
Exactly the reverse of the truth: The loop will evaluate the end_of_text
as not answering it's condition that end_of_text be false.
> not !end_of_text will actually equal to end_of_text != 1, i.e.
> equal 0.
Since end_of_text is true (1), !end_of_text == 0. The expression
end_of_text != 1 would also have a value of 0. So you're right, they are
equal, but the expression end_of_text != 1 has absolutely no relevance
to this code. Therefore the fact that both expressions have a value of 0
is equally irrelevant.
> - and I don't see any other condition for the while loop to terminate
Which is fine - the condition you've already mentioned is sufficient to
terminate it.
--
James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2015-11-10 14:01 -0500 |
| Message-ID | <n1tepq$vdd$1@dont-email.me> |
| In reply to | #75626 |
On 11/10/2015 12:11 PM, James Kuyper wrote:
...
> I don't understand what it is that you're misunderstanding about while()
> loops, but it's something pretty major. We've all repeatedly tried to
> explain to you how they work, and you keep coming up with nonsense like
> this which suggests that you haven't understood a word that we've said
> about the matter. It's very frustrating.
I want to try to get to the heart of what it is that you are
misunderstanding. Therefore, I'm going to give you a list of statements,
all of which are, to the best of my knowledge, true. For each statement,
I want you state one of the following:
A) I understand why this statement is true.
B) I think that this statement is false, because [explain your reason]
C) I cannot determine whether I think this statement is true or false.
The thing about this statement that confuses me is [explain your confusion].
1. Syntax of the while statement:
while(expression) statement
The controlling expression of a while statement is often called it's
"condition". The statement controlled by a while statement is often
called the body of the loop. The body is often a compound statement,
beginning with '{' and ending in a '}';
2. Semantics of the while statement:
first step: the controlling expression is evaluated.
If the value of that expression compares equal to 0, the loop terminates.
Otherwise, the body of the loop is executed, and then execution of the
program goes back to the first step.
I've deliberately simplified this explanation by leaving out the many
different ways in which the execution of the loop can be interrupted.
For now, concentrate on understanding the above explanation.
3. The ! operator:
If x compares equal to 0, then !x is 1; otherwise, !x is 0.
Consider the following code:
bool end_of_text = false;
while(!end_of_text)
{
// Body of loop
}
From what you've said before, you don't understand why the body of this
loop gets executed, and I'm going to concentrate my attention on that
misconception, so I haven't bothered with the details of what's in the
body of the loop.
4. !end_of_text is the condition of that loop
5. Because of statement 2 above, the loop shown above starts by
evaluating the expression !end_of_text.
6. The first time through the loop, end_of_text has a value of false (==0).
7. Therefore, the expression !end_of_text has a value of 1 (== true).
8. The condition of the loop therefore does NOT compare equal to 0.
9. Therefore, the body of the loop should be executed.
It seems to me that at this point, you must either agree that you now
understand why the body of the loop will be executed, or you will have a
problem with one or more of the above statements. If you can make it
clear which of those statements is the problem, we may be able to help
you understand this code.
--
James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-11-10 08:30 -0800 |
| Message-ID | <lnr3jxvmut.fsf@kst-u.example.com> |
| In reply to | #75569 |
Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
> Alla _ <modelling.data@gmail.com> writes:
> <snip>
>> Exactly. This what I was thinking about, but in that program
>> the author doesn't have EOF condition that turns end_of_text
>> to true, but the condition when the user has not entered any
>> text at all, i.e. text[0] = '\0'. This what confuses me.
>> It would be clear had they offered the EOF condition.
>> Given they didn't, I don't see why the loop should ever
>> terminate.
>
> This is a very interesting remark, though I'm not sure how to help
> dislodge you from this misunderstanding.
I'm not at all sure that this is a misunderstanding, or at least that
it's the one you assume it is.
> You are saying that this is
> clear:
>
> while (end_of_text == 0)
> {
> int ch = fgetc(stdin);
> if (ch == EOF)
> end_of_text = 1;
> else /* do something with the data */
> }
>
> but this
>
> while (end_of_text == 0)
> {
> read_line(text)
> if (text[0] == '\0')
> end_of_text = 1;
> else /* do something with the data */
> }
>
> is not. Mainly, it seems, because the first refers to EOF. Most
> experienced programmer will see these two as slight variation of the
> same pattern.
I'm not sure of that, but it depends on the behavior of the read_line()
function. Based on the code that calls it:
char text[81];
...
read_line (text);
my guess is that read_line() is similar to gets(), except that it
(probably) arbitrarily restricts the input to 80 characters. I don't
see any way to distinguish between an empty line input and an
end-of-file condition. (Perhaps it returns a value that the code
ignores?)
In short, due to apparent limitations in the read_line() function, the
original code terminates on an empty line, not (just) at end-of-file.
It would be useful to see a specification of the read_line() function.
In particular, what does it do (a) at end-of-file, and (b) when reading
an empty line?
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2015-11-10 09:07 -0800 |
| Message-ID | <7557bd69-d93f-4197-a72a-48f71f7614dd@googlegroups.com> |
| In reply to | #75598 |
<snip>
Here is the read_line() function:
void read_line (char buffer [])
{
char character;
int i = 0;
do
{
character = getchar();
buffer[i] = character;
i++;
}
while (character != '\n');
buffer[i - 1] = '\0';
}
It terminates when the '\n' is entered.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-11-10 09:29 -0800 |
| Message-ID | <lnvb99u5jg.fsf@kst-u.example.com> |
| In reply to | #75622 |
Alla _ <modelling.data@gmail.com> writes:
> <snip>
>
> Here is the read_line() function:
> void read_line (char buffer [])
> {
> char character;
> int i = 0;
>
> do
> {
> character = getchar();
> buffer[i] = character;
> i++;
> }
> while (character != '\n');
>
> buffer[i - 1] = '\0';
> }
>
> It terminates when the '\n' is entered.
And that function was provided for you as part of the course?
I'm not going to judge the competence of your teacher(s) based on one
function, but that's horrid. It's actually worse than gets(), which was
so inherently unsafe it was removed from the language. (If you wrote it
yourself, please consider my criticism to be toned down by a couple of
order of magnitude.)
If the user types more input than will fit into the buffer, it just
keeps storing characters past the end of the buffer. And unlike gets(),
it doesn't handle end-of-file or error conditions at all; it just
assumes they'll never happen. If I type Ctrl-D on a Unix-like system,
or Ctrl-Z on Windows, it goes into an infinite loop.
I suggest using fgets(), checking the value it returns (which tells you
if you've reached end-of-file) and dealing with the '\n' that it leaves
at the end if the buffer yourself.
char line[81];
if (fgets(line, sizeof line, stdin) == NULL) {
/* end-of-file or error; call feof(stdin) or ferror(stdin)
to find out which */
}
else {
const size_t len = strlen(line);
if (line[len-1] == '\n') {
line[len-1] = '\0';
}
}
If the input line is longer than 80 characters, the remainder of the
line will be left for reading by the next call.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2015-11-10 11:02 -0800 |
| Message-ID | <d68831c0-2df8-4060-93dc-f326708cd1a1@googlegroups.com> |
| In reply to | #75635 |
On Tuesday, November 10, 2015 at 9:29:30 PM UTC+4, Keith Thompson wrote:
> Alla _ <modelling.data@gmail.com> writes:
> > <snip>
> >
> > Here is the read_line() function:
> > void read_line (char buffer [])
> > {
> > char character;
> > int i = 0;
> >
> > do
> > {
> > character = getchar();
> > buffer[i] = character;
> > i++;
> > }
> > while (character != '\n');
> >
> > buffer[i - 1] = '\0';
> > }
> >
> > It terminates when the '\n' is entered.
>
> And that function was provided for you as part of the course?
>
It is from Kochan's book Programming in C - the one that Ben has once
severely criticized )) but this book has been suggested by cs50 staff.
I've been chastised many times here for posting codes from this book )))
However, thanks to this criticism, I have learned a lot - I truly think it's one of the best methods.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-11-10 11:33 -0800 |
| Message-ID | <ln7flptzt0.fsf@kst-u.example.com> |
| In reply to | #75658 |
Alla _ <modelling.data@gmail.com> writes:
> On Tuesday, November 10, 2015 at 9:29:30 PM UTC+4, Keith Thompson wrote:
>> Alla _ <modelling.data@gmail.com> writes:
>> > <snip>
>> >
>> > Here is the read_line() function:
>> > void read_line (char buffer [])
>> > {
>> > char character;
>> > int i = 0;
>> >
>> > do
>> > {
>> > character = getchar();
>> > buffer[i] = character;
>> > i++;
>> > }
>> > while (character != '\n');
>> >
>> > buffer[i - 1] = '\0';
>> > }
>> >
>> > It terminates when the '\n' is entered.
>>
>> And that function was provided for you as part of the course?
>>
> It is from Kochan's book Programming in C - the one that Ben has once
> severely criticized )) but this book has been suggested by cs50 staff.
> I've been chastised many times here for posting codes from this book
> ))) However, thanks to this criticism, I have learned a lot - I truly
> think it's one of the best methods.
Then I seriously suggest that you find a different book. If the rest of
the book is anything like this function, then its author is not just
failing to teach C. He's misinforming you. (Schildt is another author
to avoid, for similar reasons.)
Does the author acknowledge the problems with this read_line() function?
Does he provide a safer alternative later? If so, then this might be
excusable.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2015-11-11 00:28 -0800 |
| Message-ID | <cee1605c-0e59-446a-b940-ba59caff9af6@googlegroups.com> |
| In reply to | #75670 |
> Does the author acknowledge the problems with this read_line() function? > Does he provide a safer alternative later? I don't recall him doing so. May I ask for an advice on a book that teaches professional coding and helps to develop correct coding principles, unlike Kochan's one? I will understand if you are not willing to provide such advices. Thank you!
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | comp.lang.c
csiph-web