# Calculator

Discussion in 'C Programming' started by Flipke, May 9, 2005.

1. ### FlipkeGuest

Hello,

I wanna make a calculator where i can give the input in one word. for
example : (15*3) / (2+3)
I think i most read this in as a string and then share it in different parts
to do the calculation. But i don't now how tho start with it. Can somebody
help me.

Flipke, May 9, 2005

2. ### David ResnickGuest

Flipke wrote:
> Hello,
>
> I wanna make a calculator where i can give the input in one word. for
> example : (15*3) / (2+3)
> I think i most read this in as a string and then share it in

different parts
> to do the calculation. But i don't now how tho start with it. Can

somebody
> help me.
>

to get started on your homework.

You could also google for "recursive descent parser", that being a
standard approach for this sort of problem. K&R also has an
calculator, though
their example program uses RPN.

-David

David Resnick, May 9, 2005

3. ### Mike WahlerGuest

"Flipke" <> wrote in message
news:...
> Hello,
>
> I wanna make a calculator where i can give the input in one word. for
> example : (15*3) / (2+3)
> I think i most read this in as a string and then share it in different
> parts
> to do the calculation.

Yes, 'divide and conquer' is a good practice in programming.

First, as you said, read the input. The next step
is to parse it into meaningful segments (e.g. (15 * 3),
15, etc.). You'll need to keep track of the parentheses
in order to implement the correct precedence of the
arithmetic operations. A recursive approach is the most
common approach to this kind of problem.

>Can somebody
> help me.

write it for you. Show the code of your best attempt, and

-Mike

Mike Wahler, May 9, 2005
4. ### Julian V. NobleGuest

Flipke wrote:
>
> Hello,
>
> I wanna make a calculator where i can give the input in one word. for
> example : (15*3) / (2+3)
> I think i most read this in as a string and then share it in different parts
> to do the calculation. But i don't now how tho start with it. Can somebody
> help me.
>

Have a look at Kruse, "Data Structures and Program Design". He shows how
to develop a simple formula evaluator. IIRC he uses a parse tree rather
than recursive descent. His original version used Pascal, but that's close
enough to C to translate. Or you might look at a more recent edition--
I think he has ceased fighting the inevitable and now uses C or C++ as his
illustration language.

--
Julian V. Noble
Professor Emeritus of Physics

^^^^^^^^^^^^^^^^^^
http://galileo.phys.virginia.edu/~jvn/

"For there was never yet philosopher that could endure the
toothache patiently."

Julian V. Noble, May 9, 2005
5. ### Neil KurzmanGuest

Flipke wrote:

> Hello,
>
> I wanna make a calculator where i can give the input in one word. for
> example : (15*3) / (2+3)
> I think i most read this in as a string and then share it in different parts
> to do the calculation. But i don't now how tho start with it. Can somebody
> help me.
>

As I recall in data structures you can use stacks to convert it to RPN, then
push that on to 2 stacks to calculate it.
BTW the question is off topic.

Neil Kurzman, May 10, 2005
6. ### osmiumGuest

"Julian V. Noble" writes:

> Flipke wrote:
>>
>> Hello,
>>
>> I wanna make a calculator where i can give the input in one word. for
>> example : (15*3) / (2+3)
>> I think i most read this in as a string and then share it in different
>> parts
>> to do the calculation. But i don't now how tho start with it. Can
>> somebody
>> help me.
>>

>
> Have a look at Kruse, "Data Structures and Program Design". He shows how
> to develop a simple formula evaluator. IIRC he uses a parse tree rather
> than recursive descent. His original version used Pascal, but that's close
> enough to C to translate. Or you might look at a more recent edition--
> I think he has ceased fighting the inevitable and now uses C or C++ as his
> illustration language.

Just out of curiosity I looked up the C/C++ version of the Kruse book on
Amazon to read the reviews. I have never seen such a collection of hateful
reviews of a book! I don't think it is possible to "salt" Amazon without a
great deal of effort so the book is likely despised by these people (31),
mostly students. As I understand it, he uses STL to explain data structures
which seems like a bad approach to me. A data structures class should be
*writing* STL , not *using* it. In any event I simply must see a copy of
this book. AFAIK there is no ACCU review.

Back to the OPs question. My guess is that most of the answers are too
high falutin' for what he is expected to do. If this is a first semester
class, surely the instructor doesn't expect him to get into recursive
descent parsers and all that stuff. I would expect a student in a later
course to phrase the question differently. And there is also the slim
possibility that it isn't a student problem at all.

osmium, May 10, 2005
7. ### italyGuest

Flipke wrote:
> Hello,
>
> I wanna make a calculator where i can give the input in one word. for
> example : (15*3) / (2+3)

It's an expression, not a word. (note an expression is a collection of
operands and operators, or in some cases only operand(s))

> I think i most read this in as a string and then share it in

different parts
> to do the calculation. But i don't now how tho start with it. Can

somebody
> help me.

Break the problem down. I recommend writing a simple RPN calculator
first, because it's the easiest.
>

italy, May 10, 2005
8. ### Walter RobersonGuest

In article <>,
osmium <> wrote:
>Just out of curiosity I looked up the C/C++ version of the Kruse book on
>Amazon to read the reviews. I have never seen such a collection of hateful
>reviews of a book! I don't think it is possible to "salt" Amazon without a
>great deal of effort so the book is likely despised by these people (31),
>mostly students.

There was a scandal not long ago in which it turned out that
a bunch of Amazon "reviewers" were the authors themselves -- and
sometimes more than one "review" of their own books. "Salting" Amazon
is, then, perhaps a bit easier than you might expected.
[NB, I know nothing about the merits of the book in question.]
--
"No one has the right to destroy another person's belief by
demanding empirical evidence." -- Ann Landers

Walter Roberson, May 10, 2005
9. ### MalcolmGuest

"Flipke" <> wrote
>
> I wanna make a calculator where i can give the input in one word. for
> example : (15*3) / (2+3)
> I think i most read this in as a string and then share it in different
> parts
> to do the calculation. But i don't now how tho start with it. Can somebody
> help me.
>

To write a parser, firstly many of the rules of good programming don't apply
to parsers.
Normally the caller should ensure that the input is valid. For a parser, the
caller cannot do this without without writing another parser himself. So you
have to be very careful about handling errors.
Normally you should not have mutually recursive functions. For a parser,
this structure is natural.
Normally you should not have global variables. A parser is one place where
code is often neater if you do use globals.

How do you do it? The basic principle is that when you hit a bracket, you
call the top-level function on the contents. This is why parsers are
mutually recursive.

Arithmetical expressions have the bodmas (brackets, of, divide, multiply,

What you want to do is declare a global pointer to input so far. Then you
write a function called gettoken() which returns the token (number,
operator, parentheses) in the input stream, but does not remove it. Then
write a function called match() which discards the token from the stream,
but only if it is of the type passed. Otherwise it flags an error.

Then write three functions, expression(), term() and factor(). A factor is
either a raw number or an open parenthesis containing an expression
(recursion). A term is either a raw factor, or a series of factos connected
by divides and multiplies. An expression is either a raw term, or a series
of terms connected by additions and subtractions.

Once you have all this working, you basically have your calculator. It is
quite hard, so post your attempt if you get stuck.

Malcolm, May 10, 2005
10. ### Walter RobersonGuest

In article <d5rc47\$mlu\$-infra.bt.com>,
Malcolm <> wrote:
>To write a parser, firstly many of the rules of good programming don't apply
>to parsers.

>Normally the caller should ensure that the input is valid.

[Good] programs are full of "validate" functions which don't know if
their input is valid until they look at it.

A database "find and lock" (to avoid race conditions) routine won't
know whether the input field is a match until it does the search.

It's normal defensive programming to assume that the input might not
be valid and to protect against such cases. Think of all the verbage
about how strcpy() is a fault in the design of C and it becomes clear
that it's often a bad idea to -assume- that all necessary checks
have been done before a routine is called.

>Normally you should not have mutually recursive functions.

Sez who? ;-)

The difficulty with mutually recursive functions is in the possibility
of indefinite stack space usage. The alternative to recursive functions
is to write the equivilent iterative function -- but the equivilent
iterative function will often need indefinite memory allocation
and so suffer the same fate [except that you can detect failed
memory allocation but you can't detect whether there's enough room
to call any particular function.]

>Normally you should not have global variables.

Ah? This is comp.lang.c . The operation of fopen() and kin use
global variables almost by definition, and there's no other I/O
operators available, so compliant hosted programs will almost always
use global variables.
--
"No one has the right to destroy another person's belief by
demanding empirical evidence." -- Ann Landers

Walter Roberson, May 10, 2005

In article <d5rdih\$eo7\$>,
-cnrc.gc.ca (Walter Roberson) wrote:

> In article <d5rc47\$mlu\$-infra.bt.com>,
> Malcolm <> wrote:
> >
> >Normally you should not have global variables.

>
> Ah? This is comp.lang.c . The operation of fopen() and kin use
> global variables almost by definition, and there's no other I/O
> operators available, so compliant hosted programs will almost always
> use global variables.

How's that? I can store a FILE * in any number of ways, none of which
require global variables.

If you're saying that stdin, stdout, and stderr are globals, what does
it matter?

Cheers,
- jonathan

12. ### Keith ThompsonGuest

> In article <d5rdih\$eo7\$>,
> -cnrc.gc.ca (Walter Roberson) wrote:
>> In article <d5rc47\$mlu\$-infra.bt.com>,
>> Malcolm <> wrote:
>> >
>> >Normally you should not have global variables.

>>
>> Ah? This is comp.lang.c . The operation of fopen() and kin use
>> global variables almost by definition, and there's no other I/O
>> operators available, so compliant hosted programs will almost always
>> use global variables.

>
> How's that? I can store a FILE * in any number of ways, none of which
> require global variables.

Sure but the FILE object it points to is almost certainly global.

> If you're saying that stdin, stdout, and stderr are globals, what does
> it matter?

I'm not sure what you're asking.

--
Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.

Keith Thompson, May 11, 2005
13. ### PurnankGuest

Re: Calculator [ot]

"Mike Wahler" <> wrote in message
news:C8Kfe.10765\$...
>
> "Flipke" <> wrote in message
> news:...
> > Hello,
> >
> > I wanna make a calculator where i can give the input in one word. for
> > example : (15*3) / (2+3)
> > I think i most read this in as a string and then share it in different
> > parts
> > to do the calculation.

>
> Yes, 'divide and conquer' is a good practice in programming.

No, Divide and conquer is not the solution,
the solution is tranform / convert.

(15*3) / (2+3) --> this is not the thing you need. you may divide it upto a
small level but after some stage, things would not be as easy.
Convert the problem into Reverse Polish Notation.

(15*3) / (2 + 3)
===
You differntite operations and operands,

e.g.
2+3 is written as + 2 3
3*2 + 1
should be written as
+ * 3 2 1
Add the product of 3 and 2 to one.

+ _*_3_2_ 1
+ 6 1
7

To start with, do not use 15 , 16 ( 2 digit numbers, use 1 digit number, and
+ * - as simple operators. )

Then convert into POLISH notations.

"you need to go to *algorithms* not *lang.c*"

> First, as you said, read the input. The next step
> is to parse it into meaningful segments (e.g. (15 * 3),
> 15, etc.). You'll need to keep track of the parentheses
> in order to implement the correct precedence of the
> arithmetic operations. A recursive approach is the most
> common approach to this kind of problem.
>
>
> >Can somebody
> > help me.

>
> Yes, but we need something to help you with. Nobody will
> write it for you. Show the code of your best attempt, and
>
> -Mike
>
>

Purnank.

Purnank, May 11, 2005
14. ### Julian V. NobleGuest

osmium wrote:
>
> "Julian V. Noble" writes:
>
> > Have a look at Kruse, "Data Structures and Program Design". He shows how
> > to develop a simple formula evaluator. IIRC he uses a parse tree rather
> > than recursive descent. His original version used Pascal, but that's close
> > enough to C to translate. Or you might look at a more recent edition--
> > I think he has ceased fighting the inevitable and now uses C or C++ as his
> > illustration language.

>
> Just out of curiosity I looked up the C/C++ version of the Kruse book on
> Amazon to read the reviews. I have never seen such a collection of hateful
> reviews of a book! I don't think it is possible to "salt" Amazon without a
> great deal of effort so the book is likely despised by these people (31),
> mostly students. As I understand it, he uses STL to explain data structures
> which seems like a bad approach to me. A data structures class should be
> *writing* STL , not *using* it. In any event I simply must see a copy of
> this book. AFAIK there is no ACCU review.

Well, I rather liked the book and found it helpful when I first encountered
the Pascal version back in the late 1980's. I see some of the reviewers really
trashed it. Possibly the 2nd edition of the C version (revised by colaborators)
isn't as good as the original. That would come as no surprise---I can name half
a dozen texts that were first rate in their original edition and that got pro-
gressively worse with each succeeding one.

--
Julian V. Noble
Professor Emeritus of Physics

^^^^^^^^^^^^^^^^^^
http://galileo.phys.virginia.edu/~jvn/

"For there was never yet philosopher that could endure the
toothache patiently."

Julian V. Noble, May 11, 2005

In article <>,
Keith Thompson <> wrote:

> > In article <d5rdih\$eo7\$>,
> > -cnrc.gc.ca (Walter Roberson) wrote:
> >> In article <d5rc47\$mlu\$-infra.bt.com>,
> >> Malcolm <> wrote:
> >> >
> >> >Normally you should not have global variables.
> >>
> >> Ah? This is comp.lang.c . The operation of fopen() and kin use
> >> global variables almost by definition, and there's no other I/O
> >> operators available, so compliant hosted programs will almost always
> >> use global variables.

> >
> > How's that? I can store a FILE * in any number of ways, none of which
> > require global variables.

>
> Sure but the FILE object it points to is almost certainly global.

Which, if true,[1] would be an implementation detail of libc that
doesn't impact its users. The interface is all in terms of FILE
pointers.

The basic advice "Normally you should not have global variables" is
reasonably sound, if a little too black-and-white. At the very least,
global variables should be used with care.

Cheers,
- jonathan

[1] I've seen versions of libc which dynamically allocates their FILE
*s, beyond a certain point. For example, the Solaris implementation.
I'm fairly certain any reasonably modern UNIX will do so. stdin,
stdout, and stderr all have to be statically allocated, of course.

16. ### Walter RobersonGuest

In article <>,
>> > In article <d5rdih\$eo7\$>,
>> > -cnrc.gc.ca (Walter Roberson) wrote:

>> >> The operation of fopen() and kin use
>> >> global variables almost by definition, and there's no other I/O
>> >> operators available, so compliant hosted programs will almost always
>> >> use global variables.

>stdin,
>stdout, and stderr all have to be statically allocated, of course.

C89 indicates that they are "expressions" of type FILE*, so
in -theory- they could perhaps be functions that return the appropriate
address, such as an address of a static variable with file scope
that would -require- that globals be used for those three. On the
other hand, I don't think I have ever run into an implementation where
they weren't globals. (Hence my qualification "almost by definition".)
--
Are we *there* yet??

Walter Roberson, May 11, 2005
17. ### MalcolmGuest

>
> Which, if true,[1] would be an implementation detail of libc that
> doesn't impact its users. The interface is all in terms of FILE
> pointers.
>
> The basic advice "Normally you should not have global variables" is
> reasonably sound, if a little too black-and-white. At the very least,
> global variables should be used with care.
>

One of the weaknesses of C is that there is no distinction between a
"function", which calculates something, and a "procedure" which does
something, i.e. interacts with hardware.
Procedures naturally contain global variables, because the computer is
attached to various shared devices. Functions don't (though malloc() is a
special case), because a function is naturally defined by its parameters.
Good design normally involves separating your functions from your
procedures.

Malcolm, May 11, 2005
18. ### Keith ThompsonGuest

"Malcolm" <> writes:
[...]
> One of the weaknesses of C is that there is no distinction between a
> "function", which calculates something, and a "procedure" which does
> something, i.e. interacts with hardware.
> Procedures naturally contain global variables, because the computer is n
> attached to various shared devices. Functions don't (though malloc() is a
> special case), because a function is naturally defined by its parameters.
> Good design normally involves separating your functions from your
> procedures.

What some languages (e.g., Pascal) call a "procedure" is simply a
function returning void in C. There's no implication that a procedure
interacts with hardware and/or refers to global variables, nor is
there any particular implication (apart from style, perhaps) that a
function doesn't. A procedure can interact only through its
parameters just as easily as a function can interact only through its
parameters and result. The only difference is that a procedure
doesn't return a value.

A trivial example:

void increment(int *n)
{
*n ++;
}

Perhaps you're using the term "procedure" to refer to some other
concept.

--
Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.

Keith Thompson, May 11, 2005
19. ### Mark McIntyreGuest

Re: Calculator [ot]

On Wed, 11 May 2005 18:04:05 +0530, in comp.lang.c , "Purnank"
<> wrote:

>Convert the problem into Reverse Polish Notation.

What on earth for? Simply write a parser (or better yet, download one
already-written and tested) , and move on.

>"you need to go to *algorithms* not *lang.c*"

this is correct.

--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>

----== Posted via Newsfeeds.Com - Unlimited-Uncensored-Secure Usenet News==----
http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
----= East and West-Coast Server Farms - Total Privacy via Encryption =----

Mark McIntyre, May 12, 2005
20. ### Richard BosGuest

"Malcolm" <> wrote:

> >
> > Which, if true,[1] would be an implementation detail of libc that
> > doesn't impact its users. The interface is all in terms of FILE
> > pointers.
> >
> > The basic advice "Normally you should not have global variables" is
> > reasonably sound, if a little too black-and-white. At the very least,
> > global variables should be used with care.

>
> One of the weaknesses of C is that there is no distinction between a
> "function", which calculates something, and a "procedure" which does
> something, i.e. interacts with hardware.

You forget a "functure", which interacts with the hardware and then
calculates something from the result; a "fucedure", which calculates
something and then sends the result to hardware; and a "procion", which
neither interacts with hardware, nor calculates something.

Gosh. Am I dismayed at the lack of such a proliferation of routine types
in C! We must've been living in the dark ages of computing for years,
when we could have had all these separate "functions" and "procedures",
all with their own declaration types, to enliven our code! Makes me want
to bail out of C and start using ADA, that, it really does.

Richard

Richard Bos, May 13, 2005