Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #76744 > unrolled thread
| Started by | Alla _ <modelling.data@gmail.com> |
|---|---|
| First post | 2015-11-21 02:34 -0800 |
| Last post | 2015-11-24 06:07 -0800 |
| Articles | 20 on this page of 21 — 8 participants |
Back to article view | Back to comp.lang.c
getop() function: understanding of the code Alla _ <modelling.data@gmail.com> - 2015-11-21 02:34 -0800
Re: getop() function: understanding of the code Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-11-21 11:00 +0000
Re: getop() function: understanding of the code Alla _ <modelling.data@gmail.com> - 2015-11-21 04:24 -0800
Re: getop() function: understanding of the code Barry Schwarz <schwarzb@dqel.com> - 2015-11-21 10:01 -0800
Re: getop() function: understanding of the code Alla _ <modelling.data@gmail.com> - 2015-11-22 08:59 -0800
Re: getop() function: understanding of the code Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-11-22 09:37 -0800
Re: getop() function: understanding of the code Keith Thompson <kst-u@mib.org> - 2015-11-22 12:45 -0800
Re: getop() function: understanding of the code Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-11-22 14:53 -0800
Re: getop() function: understanding of the code Keith Thompson <kst-u@mib.org> - 2015-11-22 21:14 -0800
Re: getop() function: understanding of the code Tim Rentsch <txr@alumni.caltech.edu> - 2015-11-25 10:44 -0800
Re: getop() function: understanding of the code David Thompson <dave.thompson2@verizon.net> - 2015-12-06 08:05 -0500
Re: getop() function: understanding of the code Keith Thompson <kst-u@mib.org> - 2015-12-06 17:46 -0800
Re: getop() function: understanding of the code Barry Schwarz <schwarzb@dqel.com> - 2015-11-22 12:03 -0800
Re: getop() function: understanding of the code Alla _ <modelling.data@gmail.com> - 2015-11-22 23:29 -0800
Re: getop() function: understanding of the code Alla _ <modelling.data@gmail.com> - 2015-11-23 00:02 -0800
Re: getop() function: understanding of the code Barry Schwarz <schwarzb@dqel.com> - 2015-11-23 02:09 -0800
Re: getop() function: understanding of the code Alla _ <modelling.data@gmail.com> - 2015-11-24 00:15 -0800
Re: getop() function: understanding of the code Barry Schwarz <schwarzb@dqel.com> - 2015-11-24 01:46 -0800
Re: getop() function: understanding of the code Alla _ <modelling.data@gmail.com> - 2015-11-24 01:52 -0800
Re: getop() function: understanding of the code Philip Lantz <prl@canterey.us> - 2015-11-24 02:15 -0800
Re: getop() function: understanding of the code Alla _ <modelling.data@gmail.com> - 2015-11-24 06:07 -0800
Page 1 of 2 [1] 2 Next page →
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2015-11-21 02:34 -0800 |
| Subject | getop() function: understanding of the code |
| Message-ID | <385280d6-97ca-4e73-bf02-7f7fe8b8e629@googlegroups.com> |
Hello!
I would be grateful if you check my understanding of the getop() function,
the one from the previous thread.
I decided to share this, because obviously there are moments when I incorrectly
read the code.
The example to work with:
12+
int getch (void);
void ungetch (int c);
int getop (char s[])
{
int i, c;
while ((s[0] = c = getch()) == ' ' || c == '\t')
;
s[1] = '\0';
if (!isdigit(c) && c != '.')
{
return c;
}
i = 0;
if (isdigit(c))
{
while (isdigit(s[++i] = c = getch()))
;
}
if (c == '.')
{
while (isdigit(s[++i] = c = getch()))
;
}
s[i] = '\0';
if (c != EOF)
{
ungetch(c);
}
return NUMBER;
}
When called getop() gets an array of characters named s.
1. Start the function from the while loop (we have already
discussed how it works):
- reads the character from the input, and assigns its value to c;
- assigns c to s[0];
- then checks is c = ' ' or '\t'
In the given example, the loop stops after that check because c = '1'.
At this moment s[0] = '1'.
2. Next if statement checks if the value of c, which is assigned to
s[0], hence the value of s[0], is not digit and not dot; the result is
false, because 1 is a digit.
3. Next if statement checks if the value of c is digit. Yes, it is
digit. Therefore the while loop starts:
- gets next value from the input, and assigns it to s[1] (s[++i],
i was 0, hence now it's 1);
- checks if that value is a digit; if yes, and it is in fact a digit 2,
then the loop goes for the next round;
- gets the next value of c, assigns it to s[2], checks if it is a
digit; no, it is not, it's '+';
- loop stops with the s[2] = '+'.
3. s[i] = '\0': i has not been incremented after the break of the while loop
(i is incremented before any value is assigned to it within while loop),
hence the value of i is still 2, and the program overwrites the value of '+'
to '\0' at s[2].
4. I think it's better to leave ungetch () for now, until I know that my
above assumptions are correct.
Thank you!
[toc] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-11-21 11:00 +0000 |
| Message-ID | <87vb8vobvz.fsf@bsb.me.uk> |
| In reply to | #76744 |
Alla _ <modelling.data@gmail.com> writes:
> I would be grateful if you check my understanding of the getop() function,
> the one from the previous thread.
>
> I decided to share this, because obviously there are moments when I incorrectly
> read the code.
>
> The example to work with:
> 12+
>
> int getch (void);
> void ungetch (int c);
>
> int getop (char s[])
> {
> int i, c;
>
> while ((s[0] = c = getch()) == ' ' || c == '\t')
> ;
<moved>
> When called getop() gets an array of characters named s.
>
> 1. Start the function from the while loop (we have already
> discussed how it works):
> - reads the character from the input, and assigns its value to c;
> - assigns c to s[0];
> - then checks is c = ' ' or '\t'
> In the given example, the loop stops after that check because c = '1'.
> At this moment s[0] = '1'.
Yes, that's right. You might have chosen " 12+" as an input so this
loop could do some real work, but that's not the point here.
> s[1] = '\0';
>
>
> if (!isdigit(c) && c != '.')
> {
> return c;
> }
<moved>
> 2. Next if statement checks if the value of c, which is assigned to
> s[0], hence the value of s[0], is not digit and not dot; the result is
> false, because 1 is a digit.
Yes. Technically c and s[0] might have different values. One is an int
and the other a char. I don't know if getch() can return anything like
EOF but if it can, c and s[0] will have different values.
> i = 0;
>
> if (isdigit(c))
> {
> while (isdigit(s[++i] = c = getch()))
> ;
> }
<moved>
> 3. Next if statement checks if the value of c is digit. Yes, it is
> digit. Therefore the while loop starts:
> - gets next value from the input, and assigns it to s[1] (s[++i],
> i was 0, hence now it's 1);
> - checks if that value is a digit; if yes, and it is in fact a digit 2,
> then the loop goes for the next round;
> - gets the next value of c, assigns it to s[2], checks if it is a
> digit; no, it is not, it's '+';
> - loop stops with the s[2] = '+'.
Yes. I'd write "with the s[2] == '+'" but that hardly matters.
> if (c == '.')
> {
> while (isdigit(s[++i] = c = getch()))
> ;
> }
You didn't comment on this but it's clear you know it does not apply
here.
> s[i] = '\0';
> 3. s[i] = '\0': i has not been incremented after the break of the while loop
> (i is incremented before any value is assigned to it within while loop),
> hence the value of i is still 2, and the program overwrites the value of '+'
> to '\0' at s[2].
Yes.
> if (c != EOF)
> {
> ungetch(c);
> }
>
> return NUMBER;
> }
<snip>
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2015-11-21 04:24 -0800 |
| Message-ID | <aaa15fa7-fd61-4332-81c8-88009ff3c749@googlegroups.com> |
| In reply to | #76748 |
<snip> Thank you very much. I also see that I should have supported my comments with a relevant code, as you did.
[toc] | [prev] | [next] | [standalone]
| From | Barry Schwarz <schwarzb@dqel.com> |
|---|---|
| Date | 2015-11-21 10:01 -0800 |
| Message-ID | <vda15bhs4814b3dlunf4bpjcn0mcnd433o@4ax.com> |
| In reply to | #76744 |
On Sat, 21 Nov 2015 02:34:07 -0800 (PST), Alla _ <modelling.data@gmail.com> wrote: >Hello! > >I would be grateful if you check my understanding of the getop() function, >the one from the previous thread. <snip> Pretty close. >When called getop() gets an array of characters named s. Despite the [] notation, s is a pointer to char. >1. Start the function from the while loop (we have already >discussed how it works): > - reads the character from the input, and assigns its value to c; Despite the similarity of names, getch is not an I/O function. main receives whatever value getch decides to give it. Within the getch function, a decision is made to either return a previously saved value or a new value obtained from the input stream. main does not care which. > - assigns c to s[0]; > - then checks is c = ' ' or '\t' >In the given example, the loop stops after that check because c = '1'. The loop stops because the "while expression" evaluates to 0. This is because both operands of the || operator evaluate to 0. >At this moment s[0] = '1'. > >2. Next if statement checks if the value of c, which is assigned to >s[0], hence the value of s[0], is not digit and not dot; the result is >false, because 1 is a digit. While everything you say regarding s[0] is true, it has nothing to do with this if statement. c is the only variable being checked. >3. Next if statement checks if the value of c is digit. Yes, it is >digit. Therefore the while loop starts: > - gets next value from the input, and assigns it to s[1] (s[++i], >i was 0, hence now it's 1); Gets the next value from getch. > - checks if that value is a digit; if yes, and it is in fact a digit 2, >then the loop goes for the next round; > - gets the next value of c, assigns it to s[2], checks if it is a >digit; no, it is not, it's '+'; > - loop stops with the s[2] = '+'. You left out the next if statement. While it is false in this case, you need to understand that it would append the fractional part of the number to s if c were '.'. >3. s[i] = '\0': i has not been incremented after the break of the while loop It could be either of two while loops depending on the existence of a decimal point. >(i is incremented before any value is assigned to it within while loop), i is incremented before any value is assigned to the next "element" of s. >hence the value of i is still 2, and the program overwrites the value of '+' >to '\0' at s[2]. > >4. I think it's better to leave ungetch () for now, until I know that my >above assumptions are correct. Fine but it did affect your assumptions about getch. -- Remove del for email
[toc] | [prev] | [next] | [standalone]
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2015-11-22 08:59 -0800 |
| Message-ID | <61043f85-a4ef-4c21-add4-e2ce7e8487ce@googlegroups.com> |
| In reply to | #76744 |
<snip>
Hello!
I am trying to decipher the whole program and find out some issues. Please,
do me a favor and, although now I publish the whole program, follow my questions and do not comment on any other parts of this program until my
questions are resolved, because I am trying to understand each part before
summing up the whole.
I would like to say "Thank you" here, because the program is long )
The goal of the program is to demonstrate the implementation of reverse polish
notation. Authors suggest the following example: 12-45+*. I am using
a short version 12+ (also changed the sign, but that doesn't play any role).
getop() was one of the main parts. As discussed previously, and given the same
example 12+:
1. the main function starts by calling getop() function;
getop(), as discussed, finishes with s[0] = 1, s[1] = 2, s[2] = '\0';
the variable c at the end of getop() still holds the value of '+';
hence, getop() calls ungetch() to assign the value of '+' to buf[0], and
leave buf[1] equal to some abstract value, because buf has been
incremented after buf[0] has been assigned the value of '+';
if (c != EOF)
> {
> ungetch(c);
> }
void ungetch (int c)
{
if (bufp >= BUFSIZE)
{
printf("ungetch: too many characters\n");
}
else
{
buf[bufp++] = c;
}
}
2. the main function receives NUMBER from getop() call, and thus enters
Case NUMBER, and calls push(atof(s));
while ((type = getop(s)) != EOF)
{
switch (type)
{
case NUMBER:
push(atof(s));
<snip>
2.1. atof(s) should convert numbers in array s into a double value;
and then this double value should be assigned to val[sp] by push()
function;
do I understand correctly that if s[0] = 1 and s[1] = 2, then atof(s)
produces 12.000000? I have tested both push() and atof() by extracting
them from the big program and putting into a test version (I publish
it below the big program).
// Program to apply reverse Polish notation
#include <stdio.h>
#include <stdlib.h> /* for atof() */
#include <ctype.h>
#define MAXOP 100 /* max size of operand or operator */
#define NUMBER '0' /* signal that a number was found */
int getop(char []);
void push(double);
double pop(void);
int main(void)
{
int type;
double op2;
char s[MAXOP];
while ((type = getop(s)) != EOF)
{
switch (type)
{
case NUMBER:
push(atof(s));
break;
case '+':
push(pop() + pop());
break;
case '*':
push(pop() * pop());
break;
case '-' :
op2 = pop();
push (pop () - op2);
break;
case '/':
op2 = pop();
if (op2 != 0.0)
push(pop() / op2);
else
printf("error: zero divisor\n");
break;
case '\n':
printf ("\t%.8g\n", pop ());
break;
default:
printf("error: unknown command %s\n", s);
break;
}
}
return 0;
}
#define MAXVAL 100 /* maximum depth of val stack */
int sp = 0; /* next free stack position */
double val [MAXVAL]; /* value stack */
/* push: push f onto value stack */
void push (double f)
{
if (sp < MAXVAL)
{
val[sp++] = f;
}
else
{
printf("error: stack full, can't push %g\n", f);
}
}
/* pop: pop and return top value from stack */
double pop (void)
{
if (sp > 0)
return val[--sp];
else
{
printf("error: stack empty\n");
return 0.0;
}
}
/* GETCH and UNGETCH functions */
#define BUFSIZE 100
/* buffer for ungetch */
char buf[BUFSIZE];
/* next free position in buf */
int bufp = 0;
/* get a (possibly pushed back) character */
int getch (void)
{
return (bufp > 0) ? buf[--bufp] : getchar();
}
/* push character back on input */
void ungetch (int c)
{
if (bufp >= BUFSIZE)
{
printf("ungetch: too many characters\n");
}
else
{
buf[bufp++] = c;
}
}
/* getop: get next operator or numeric operand */
int getop (char s[])
{
int i, c;
while ((s[0] = c = getch()) == ' ' || c == '\t')
;
s[1] = '\0';
/* could be written as:
while((c=getch()) == ' ' || c == '\t');
s[0] = c;
or
while ((c = getch()) == ' ' || c == '\t')
continue;
*/
if (!isdigit(c) && c != '.')
{
return c; /* not a number */
}
i = 0;
if (isdigit(c)) /* collect integer part */
{
while (isdigit(s[++i] = c = getch()))
;
}
if (c == '.') /* collect fraction part */
{
while (isdigit(s[++i] = c = getch()))
;
}
s[i] = '\0';
if (c != EOF)
{
ungetch(c);
}
return NUMBER;
}
*Test atof and push* version:
#include <stdio.h>
#include <stdlib.h> /* for atof() */
#include <ctype.h>
#define MAXOP 100 /* max size of operand or operator */
#define NUMBER '0' /* signal that a number was found */
int getop(char []);
double push (double f);
int main(void)
{
int type;
double op2;
char s[MAXOP];
while ((type = getop(s)) != EOF)
{
op2 = atof(s);
push(op2);
printf("%f\n", op2);
}
return 0;
}
/* GETCH and UNGETCH functions */
#define BUFSIZE 100
/* buffer for ungetch */
char buf[BUFSIZE];
/* next free position in buf */
int bufp = 0;
/* get a (possibly pushed back) character */
int getch (void)
{
return (bufp > 0) ? buf[--bufp] : getchar();
}
/* push character back on input */
void ungetch (int c)
{
if (bufp >= BUFSIZE)
{
printf("ungetch: too many characters\n");
}
else
{
buf[bufp++] = c;
}
}
int getop (char s[])
{
int i, c;
while ((s[0] = c = getch()) == ' ' || c == '\t')
;
s[1] = '\0';
if (!isdigit(c) && c != '.')
{
return c;
}
i = 0;
if (isdigit(c))
{
while (isdigit(s[++i] = c = getch()))
;
}
if (c == '.')
{
while (isdigit(s[++i] = c = getch()))
;
}
s[i] = '\0';
if (c != EOF)
{
ungetch(c);
}
return NUMBER;
}
#define MAXVAL 100 /* maximum depth of val stack */
int sp = 0; /* next free stack position */
double val [MAXVAL]; /* value stack */
/* push: push f onto value stack */
double push (double f)
{
if (sp < MAXVAL)
{
val[sp++] = f; /* value [s] gets the value of f, and then sp is incremented */
return val[sp--];
}
else
{
printf("error: stack full, can't push %g\n", f);
}
return -1;
}
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2015-11-22 09:37 -0800 |
| Message-ID | <d50a792d-8072-4662-8bf5-bcb665ed4cc4@googlegroups.com> |
| In reply to | #76887 |
On Sunday, November 22, 2015 at 5:00:10 PM UTC, Alla _ wrote: > 1. the main function starts by calling getop() function; > getop(), as discussed, finishes with s[0] = 1, s[1] = 2, s[2] = '\0'; > the variable c at the end of getop() still holds the value of '+' > hence, getop() calls ungetch() to assign the value of '+' to buf[0], > and leave buf[1] equal to some abstract value, because buf has been > incremented after buf[0] has been assigned the value of '+'; > This is the difference between an array and a buffer. buf is a buffer. It doesn't have any data until you put data in it. The variable bufp (a misnomer, it should be bufN) tells how much data is in the buffer. The rest of the buffer is not data, it's just garbage. > > do I understand correctly that if s[0] = 1 and s[1] = 2, then atof(s) > produces 12.000000? I have tested both push() and atof() by extracting > them from the big program and putting into a test version (I publish > it below the big program). > No, s[0] must be 1, s[1] must be 2, s[2] must be a character atof() recognises as "end of number". Which I think is anything except a digit or a decimal point. You should also make sure s is nul terminated before calling a function like atof(). It probably doesn't demand a nul in fact, but it's just good practice, and it means you can print out the string easily if results are unexpected. Your approach is right, though. Write the low-level routines first and test them. eg the getch() / ungetch() system. Make sure that's working as intended, including on overflow. The the getop() function and the push / pop system. Finally the reverse Polish function.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-11-22 12:45 -0800 |
| Message-ID | <lnio4t4vbu.fsf@kst-u.example.com> |
| In reply to | #76891 |
Malcolm McLean <malcolm.mclean5@btinternet.com> writes:
> On Sunday, November 22, 2015 at 5:00:10 PM UTC, Alla _ wrote:
>> 1. the main function starts by calling getop() function;
>> getop(), as discussed, finishes with s[0] = 1, s[1] = 2, s[2] = '\0';
>> the variable c at the end of getop() still holds the value of '+'
>> hence, getop() calls ungetch() to assign the value of '+' to buf[0],
>> and leave buf[1] equal to some abstract value, because buf has been
>> incremented after buf[0] has been assigned the value of '+';
>>
> This is the difference between an array and a buffer.
No, it isn't.
Given this code:
#define BUFSIZE 100
char buf[BUFSIZE];
buf is an array object, both before and after values are assigned
to its elements.
Malcolm, you've made it clear that you think that what C calls an
"array object" isn't an "array" until values are stored in it.
You are misusing words that are clearly defined by the standard,
and introducing confusion.
Alla, I advise you to ignore this. It's true that buf doesn't
contain any meaningful data until it's been assigned. That doesn't
mean it's not an array. (It's also perfectly reasonable to call
it a "buffer", though that term is not defined by the standard in
this context.)
[...]
--
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 | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2015-11-22 14:53 -0800 |
| Message-ID | <23635c32-071e-4a27-9958-cc894f95025f@googlegroups.com> |
| In reply to | #76910 |
On Sunday, November 22, 2015 at 8:45:33 PM UTC, Keith Thompson wrote: > Malcolm McLean <malcolm.mclean5@btinternet.com> writes: > > Malcolm, you've made it clear that you think that what C calls an > "array object" isn't an "array" until values are stored in it. > You are misusing words that are clearly defined by the standard, > and introducing confusion. > The authors of the standard are ignorant of how to use words correctly. Which is unfortunate. There's a similar misuse of the term "function" to refer to something like printf(). We can only point this out. It's not just a case of being pedantic. Using the right word for the right concept is important for thinking clearly about programming.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-11-22 21:14 -0800 |
| Message-ID | <lna8q547ry.fsf@kst-u.example.com> |
| In reply to | #76938 |
Malcolm McLean <malcolm.mclean5@btinternet.com> writes:
> On Sunday, November 22, 2015 at 8:45:33 PM UTC, Keith Thompson wrote:
>> Malcolm, you've made it clear that you think that what C calls an
>> "array object" isn't an "array" until values are stored in it.
>> You are misusing words that are clearly defined by the standard,
>> and introducing confusion.
>>
> The authors of the standard are ignorant of how to use words
> correctly. Which is unfortunate.
Nonsense.
> There's a similar misuse of the
> term "function" to refer to something like printf(). We can only
> point this out.
More nonsense. C happens to use the word "function" where some other
languages use the word "subroutine", or "procedure or function". It's
entirely consistent in its usage.
> It's not just a case of being pedantic. Using the right word for
> the right concept is important for thinking clearly about programming.
Using the right word for the right concept is important for thinking
clearly about C. Misusing words that are already clearly defined causes
nothing but confusion.
--
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 | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2015-11-25 10:44 -0800 |
| Message-ID | <kfn8u5l3on4.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #76938 |
Malcolm McLean <malcolm.mclean5@btinternet.com> writes: [...] > > The authors of the standard are ignorant of how to use words > correctly. [...] If they're only half as ignorant as you are arrogant, they must be pretty ignorant.
[toc] | [prev] | [next] | [standalone]
| From | David Thompson <dave.thompson2@verizon.net> |
|---|---|
| Date | 2015-12-06 08:05 -0500 |
| Message-ID | <bic86bdkjjve9umlkf09tf9obpv9uvs926@4ax.com> |
| In reply to | #76891 |
On Sun, 22 Nov 2015 09:37:42 -0800 (PST), Malcolm McLean <malcolm.mclean5@btinternet.com> wrote: > On Sunday, November 22, 2015 at 5:00:10 PM UTC, Alla _ wrote: > > > 1. the main function starts by calling getop() function; > > getop(), as discussed, finishes with s[0] = 1, s[1] = 2, s[2] = '\0'; <snip> Actually s[0] = '1' and s[1] = '2'. In C source code, 1 and 2 are the integers that are the first numbers you learned as a child (at least for most children). '1' and '2' are the _character codes_ used to represent the characters that look like 1 and 2 _outside_ the program, for example on the display used by your programs, in files your program might read and/or write, etc. If your program reads from the keyboard and you (or someone) presses the A key, the program receives the character code 'a' or 'A' depending on whether SHIFT is also pressed (or CAPSLOCK is set). The C standard allows variation in how character codes are assigned, but in practice all the systems you will see will use either ASCII or a code that extends ASCII (like Windows-1252, ISO-8859, Unicode). _Given that_ '1' is 49 or 0x31, '2' is 50 or 0x32, 'A' is 65 or 0x41, 'a' is 97 or 0x61. (The C compiler is equally happy with decimal or 0x-hex numbers, but the way ASCII is designed makes it more convenient for people to use hex. And almost as convenient to use octal, but the notation in C for octal is more likely to be confusing, so I suggest you leave that for later.) The null character, used to terminate strings in C, is special. It is always the integer 0, which can be represented by the exactly equivalent character escape '\0' .Some people (including me) consider it better style to write '\0' when using it _as_ a null character rather than some other kind of 0, but you should know that's only a style preference not a requirement. > > do I understand correctly that if s[0] = 1 and s[1] = 2, then atof(s) > > produces 12.000000? I have tested both push() and atof() by extracting > > them from the big program and putting into a test version (I publish > > it below the big program). > > > No, s[0] must be 1, s[1] must be 2, s[2] must be a character atof() > recognises as "end of number". Which I think is anything except a > digit or a decimal point. You should also make sure s is nul terminated > before calling a function like atof(). It probably doesn't demand > a nul in fact, but it's just good practice, and it means you can > print out the string easily if results are unexpected. > Again '1' and '2' in both cases. And be careful about saying a floating-point value _is_ something like 12.345. Again the C standard allows variation but in practice the systems you see use _binary_ floating-point, which means most of the values that can be represented have long and irregular-looking decimal representations; when we input and output floating-point values in decimal, as we usuallly do, we actually get a _rounded approximation_ of the apparent value. This is usually good enough but not always. However, floating-point values that happen to be integers (the fractional part is zero) _and_ not very large (usually up to about 7 decimal digits for float or about 16 decimal digits for double) are represented exactly without rounding.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-12-06 17:46 -0800 |
| Message-ID | <ln37vfows0.fsf@kst-u.example.com> |
| In reply to | #77976 |
David Thompson <dave.thompson2@verizon.net> writes:
[...]
> The C standard allows variation in how character codes are assigned,
> but in practice all the systems you will see will use either ASCII or
> a code that extends ASCII (like Windows-1252, ISO-8859, Unicode).
[...]
Yes, that covers the vast majority of systems someone is likely to run
into.
EBCDIC covers the vast majority of the rest.
--
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 | Barry Schwarz <schwarzb@dqel.com> |
|---|---|
| Date | 2015-11-22 12:03 -0800 |
| Message-ID | <4u645b11r5or9damo1j7kids8ls177s76p@4ax.com> |
| In reply to | #76887 |
On Sun, 22 Nov 2015 08:59:39 -0800 (PST), Alla _
<modelling.data@gmail.com> wrote:
><snip>
>Hello!
>
>I am trying to decipher the whole program and find out some issues. Please,
>do me a favor and, although now I publish the whole program, follow my questions and do not comment on any other parts of this program until my
>questions are resolved, because I am trying to understand each part before
>summing up the whole.
>
>I would like to say "Thank you" here, because the program is long )
>
>The goal of the program is to demonstrate the implementation of reverse polish
>notation. Authors suggest the following example: 12-45+*. I am using
>a short version 12+ (also changed the sign, but that doesn't play any role).
>
>getop() was one of the main parts. As discussed previously, and given the same
>example 12+:
>
>1. the main function starts by calling getop() function;
>
> getop(), as discussed, finishes with s[0] = 1, s[1] = 2, s[2] = '\0';
>
> the variable c at the end of getop() still holds the value of '+';
>
> hence, getop() calls ungetch() to assign the value of '+' to buf[0], and
> leave buf[1] equal to some abstract value, because buf has been
If you look carefully, you will see that buf is defined outside of any
function. This gives it file scope and static duration. As a result,
each element of the array is automatically initialized to 0 prior to
the start of the program. At this point, buf[1] must be 0.
> incremented after buf[0] has been assigned the value of '+';
Of course you meant bufp has been incremented, not buf.
>
> if (c != EOF)
>> {
>> ungetch(c);
>> }
>
> void ungetch (int c)
>{
> if (bufp >= BUFSIZE)
> {
> printf("ungetch: too many characters\n");
> }
> else
> {
> buf[bufp++] = c;
> }
>}
>
>2. the main function receives NUMBER from getop() call, and thus enters
> Case NUMBER, and calls push(atof(s));
> while ((type = getop(s)) != EOF)
> {
> switch (type)
> {
> case NUMBER:
> push(atof(s));
><snip>
>
> 2.1. atof(s) should convert numbers in array s into a double value;
> and then this double value should be assigned to val[sp] by push()
> function;
>
> do I understand correctly that if s[0] = 1 and s[1] = 2, then atof(s)
s is an automatic variable in main that is not initialized. Therefore
each element has an indeterminate value. The fact that s[2] was set
to '\0' in getop is significant for atof to work properly.
> produces 12.000000? I have tested both push() and atof() by extracting
Most of us would write either 12. or 12.0 but yes.
<snip text of program>
--
Remove del for email
[toc] | [prev] | [next] | [standalone]
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2015-11-22 23:29 -0800 |
| Message-ID | <1feb20ec-adda-4192-9b39-ac8b719b5097@googlegroups.com> |
| In reply to | #76905 |
<snip> > If you look carefully, you will see that buf is defined outside of any > function. This gives it file scope and static duration. As a result, > each element of the array is automatically initialized to 0 prior to > the start of the program. At this point, buf[1] must be 0. > > > incremented after buf[0] has been assigned the value of '+'; > > Of course you meant bufp has been incremented, not buf. ><snip> yes, bufp. > ><snip> > > > > 2.1. atof(s) should convert numbers in array s into a double value; > > and then this double value should be assigned to val[sp] by push() > > function; > > > > do I understand correctly that if s[0] = 1 and s[1] = 2, then atof(s) > > s is an automatic variable in main that is not initialized. Therefore > each element has an indeterminate value. The fact that s[2] was set > to '\0' in getop is significant for atof to work properly. > > > produces 12.000000? I have tested both push() and atof() by extracting > > Most of us would write either 12. or 12.0 but yes. > > <snip text of program> Thank you for your answer and explanations.
[toc] | [prev] | [next] | [standalone]
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2015-11-23 00:02 -0800 |
| Message-ID | <fdc6a71b-c8fc-4cd3-8a11-ed938b366ad1@googlegroups.com> |
| In reply to | #76887 |
<snip> Thank you everyone for your helpful answers. Moving further (please, refer to the program published within my previous message; I am not sure if I have to publish it again in this message - this might again make the message too long). 1. The while loop in the main routine has finished its first iteration with the Case NUMBER being implemented, and as a result the call to push() function stored 12.000000 (I am still using this number, because that's what I get from the Terminal, hence I use it for the sake of accuracy) at val[0]. 2. Second iteration of the while loop in the main routine calls getop() function, which calls getch(). 3. Getch() returns the value that has been stored at buf[0] after the first round; hence, buf[0] = '+'. And getop() returns '+'. 4. This value is checked by the main routine, and it corresponds to Case '+'. 5. Case '+' calls push() function, which, in its turn, makes two calls to pop() function, and now I have reached the phase that I don't understand, and that doesn't allow the program to work the way it should: 5.1. first call to pop() function returns the value stored in val[0], which is 12.000000; 5.2. second call to pop() function is supposed to return the value stored in val[1], but no value has in fact been stored there; hence pop() prints the message about empty stack. Here is what I though should have happened: val[0] should have been assigned the value of 1 val[1] - value of 2 hence push(pop() + pop()) would have assigned the value of 3 to val[2] - push (1 + 2) Thank you!
[toc] | [prev] | [next] | [standalone]
| From | Barry Schwarz <schwarzb@dqel.com> |
|---|---|
| Date | 2015-11-23 02:09 -0800 |
| Message-ID | <5ko55bl6mg0t92dj6d02dilevchbfcpd70@4ax.com> |
| In reply to | #76974 |
On Mon, 23 Nov 2015 00:02:14 -0800 (PST), Alla _ <modelling.data@gmail.com> wrote: <snip> In this case, your problem is not with faulty analysis but with your choice of input. >2. Second iteration of the while loop in the main routine calls getop() >function, which calls getch(). > >3. Getch() returns the value that has been stored at buf[0] after the first >round; hence, buf[0] = '+'. And getop() returns '+'. The only way buf[0] could be '+' is if the string you entered was "12+". If that is the case, you have entered an ill-formed string. This program processes expressions in reverse Polish notation. Look at the sample input on page 74. Every binary operator in the string is preceded by at least two operands. What you should have entered is "12 45 +". >4. This value is checked by the main routine, and it corresponds to Case '+'. > >5. Case '+' calls push() function, which, in its turn, makes two calls to pop() >function, and now I have reached the phase that I don't understand, and that >doesn't allow the program to work the way it should: What this shows is that the program does not perform error analysis for the case where there are insufficient operands for the operator. The purpose of this exercise is managing push and pop operations on a queue. The authors probably did not want to clutter up the code with error checking that was unrelated to those operations. You need to rework your analysis using a well formed string as input. -- Remove del for email
[toc] | [prev] | [next] | [standalone]
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2015-11-24 00:15 -0800 |
| Message-ID | <0a7d85fb-93fb-42c2-acf5-33fee59759fd@googlegroups.com> |
| In reply to | #76976 |
On Monday, November 23, 2015 at 2:09:51 PM UTC+4, Barry Schwarz wrote: > On Mon, 23 Nov 2015 00:02:14 -0800 (PST), Alla _ > <modelling.data@gmail.com> wrote: > > <snip> > > In this case, your problem is not with faulty analysis but with your > choice of input. > > >2. Second iteration of the while loop in the main routine calls getop() > >function, which calls getch(). > > > >3. Getch() returns the value that has been stored at buf[0] after the first > >round; hence, buf[0] = '+'. And getop() returns '+'. > > The only way buf[0] could be '+' is if the string you entered was > "12+". If that is the case, you have entered an ill-formed string. > This program processes expressions in reverse Polish notation. Look > at the sample input on page 74. Every binary operator in the string > is preceded by at least two operands. > > What you should have entered is "12 45 +". I have found out how to enter the input to get a correct result, but there is nothing said on this. It should be: 1 2 - 4 5 + * You have not entered spaces between characters. I would be grateful if you explain why these spaces are crucial to get a correct result? Thank you!
[toc] | [prev] | [next] | [standalone]
| From | Barry Schwarz <schwarzb@dqel.com> |
|---|---|
| Date | 2015-11-24 01:46 -0800 |
| Message-ID | <cv985bpglgv9ir91pihuc5n1crug3pp18i@4ax.com> |
| In reply to | #77061 |
On Tue, 24 Nov 2015 00:15:39 -0800 (PST), Alla _
<modelling.data@gmail.com> wrote:
>On Monday, November 23, 2015 at 2:09:51 PM UTC+4, Barry Schwarz wrote:
>> On Mon, 23 Nov 2015 00:02:14 -0800 (PST), Alla _
>> <modelling.data@gmail.com> wrote:
>>
>> <snip>
>>
>> In this case, your problem is not with faulty analysis but with your
>> choice of input.
>>
>> >2. Second iteration of the while loop in the main routine calls getop()
>> >function, which calls getch().
>> >
>> >3. Getch() returns the value that has been stored at buf[0] after the first
>> >round; hence, buf[0] = '+'. And getop() returns '+'.
>>
>> The only way buf[0] could be '+' is if the string you entered was
>> "12+". If that is the case, you have entered an ill-formed string.
>> This program processes expressions in reverse Polish notation. Look
>> at the sample input on page 74. Every binary operator in the string
>> is preceded by at least two operands.
>>
>> What you should have entered is "12 45 +".
>
>I have found out how to enter the input to get a correct result, but there is
>nothing said on this.
>It should be: 1 2 - 4 5 + *
>You have not entered spaces between characters.
My example only showed how to get past the problem of insufficient
operands for the + operator. My sample input would have computed the
sum of 12 and 45 yielding 57. (Yes, I should have used numbers that
did not appear as if they were related to the numbers in the book.)
The sample input in the book would have produced
the product of
the difference between 1 and 2 (namely -1)
the sum of 4 and 5 (namely 9)
which is of course -9
>I would be grateful if you explain why these spaces are crucial to get a correct
>result? Thank you!
You need to be able to determine where a number ends. In this
example, a number ends at the first character that is neither a digit
nor a decimal point. The space between the 1 and the 2 is mandatory,
as is the one between the 4 and the 5. The spaces between the 2 and
the -, between the - and the 4, between the 5 and the +, and between
the + and the * are optional.
Whatever character terminates the number is passed to ungetch to be
stored in buf. The next time getop is called, this character is
retrieved by getch. If it happens to be a space, it is ignored along
with any other spaces until the next number or operator is found. Thus
the line
1 2 - 4 5 + *
would have been processed the same if it was written
1 2-4 5 +*
--
Remove del for email
[toc] | [prev] | [next] | [standalone]
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2015-11-24 01:52 -0800 |
| Message-ID | <5a2e6861-41e4-41b1-b82f-6bfc550bb5e8@googlegroups.com> |
| In reply to | #77064 |
> > You need to be able to determine where a number ends. In this > example, a number ends at the first character that is neither a digit > nor a decimal point. Oh, of course! What a shame, yet again :) It's the first while loop. Sorry that I have forgotten that.
[toc] | [prev] | [next] | [standalone]
| From | Philip Lantz <prl@canterey.us> |
|---|---|
| Date | 2015-11-24 02:15 -0800 |
| Message-ID | <MPG.30bdd8ac8325acdbb0@news.eternal-september.org> |
| In reply to | #77061 |
Alla _ wrote: > Barry Schwarz wrote: > > Alla _ wrote: > > > > In this case, your problem is not with faulty analysis but with your > > choice of input. > > > > >2. Second iteration of the while loop in the main routine calls getop() > > >function, which calls getch(). > > > > > >3. Getch() returns the value that has been stored at buf[0] after the first > > >round; hence, buf[0] = '+'. And getop() returns '+'. > > > > The only way buf[0] could be '+' is if the string you entered was > > "12+". If that is the case, you have entered an ill-formed string. > > This program processes expressions in reverse Polish notation. Look > > at the sample input on page 74. Every binary operator in the string > > is preceded by at least two operands. > > > > What you should have entered is "12 45 +". > > I have found out how to enter the input to get a correct result, but there is > nothing said on this. > It should be: 1 2 - 4 5 + * > You have not entered spaces between characters. > > I would be grateful if you explain why these spaces are crucial to get a correct > result? Thank you! I think you can figure this out--look at the code, and see what it does when it sees a digit followed by another digit, and then see what it does when it sees a digit followed by something that is not a digit.
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | comp.lang.c
csiph-web