"Mike Wahler" <mkwahler@mkwahler.net> wrote in message
news:rsKac.9792$Dv2.9695@newsread2.news.pas.earthl ink.net...[color=blue]
> "dave" <dave268@mindspring.com> wrote in message
> news:uUJac.6874$yN6.3975@newsread2.news.atl.earthl ink.net...[color=green]
> > ISBN 1-861000-88-X
> >
> > I'm confused about these references to the usage of recursion pertaining[/color]
> to[color=green]
> > example Ex6_08A:
> > On page 236 in the last sentence of the 3rd paragraph "Since any set of
> > parenthesis will contain what we've defined as an expression, they will[/color][/color]
be[color=blue][color=green]
> > taken care of automatically. Recursion wins again.[/color]
>
> We can't really assign a particular meaning to that without
> seeing it in context. "Wins" implies the superiority of one
> method over another. What other method(s) are being compared
> against, and what is the rationale presented (if any) of
> recursion being superior?
>
> Tell me in English what the program is supposed to do,
> I'll speculate that I can write it in a much clearer,
> readable, easier-to understand form.
>[color=green]
> >
> > On page 237 in the last sentence of the first paragraph: "This is[/color][/color]
really[color=blue][color=green]
> > the icing on the cake, and it's all down to the magic of recursion."
> >
> > Also, the last sentence of the first paragraph on pg. 240 ends with "all[/color]
> due[color=green]
> > to the amazing power of recursion."[/color]
>
> Many people become enamored with recursion perhaps because
> they find it somehow 'elegant'. But imo it's very often
> abused.
>[color=green]
> >
> > I had thought recursion is when a function calls itself,[/color]
>
> Yes.
>[color=green]
> >but I can't seem to
> > find this in the source code. If it's there, where ?[/color]
>
> See below (after the code).
>[color=green]
> >
> > Another point, the error checking in the Ex6_08A program on pg 236 fails[/color]
> to[color=green]
> > catch these user entry errors:
> > 6++3
> > 2**4
> > 6****7
> > 9/////2
> > 7-----5
> > etc.[/color]
>
> Well, fix it! :-)
>[color=green]
> >
> > Thank you for your assistance.
> >
> > Following is the source code listing:
> >
> > // EX6_08.CPP
> > // A program to implement a calculator
> >
> > #include <iostream> // For stream input/output
> > #include <cstdlib> // For the exit() function
> > #include <cctype> // For the isdigit() function
> > #include <string> // For the strcpy function
> > using namespace std;
> >
> > void eatspaces(char* str); // Function to eliminate blanks
> > double expr(char* str); // Function evaluating an expression
> > double term(char* str, int& index); // Function analyzing a term
> > double number(char* str, int& index); // Function to recognize a number
> > char* extract(char* str, int& index); //Function to extract a substring
> >
> > const int MAX = 80; // Maximum expression length including '\0'
> >
> > int main(void)
> > {
> > char buffer[MAX] = {0}; // Input area for expression to be[/color][/color]
evaluated[color=blue][color=green]
> >
> > cout << endl
> > << "Welcome to your friendly calculator."
> > << endl
> > << "Enter an expression, or an empty line to quit."
> > << endl;
> >
> > for(;;)
> > {
> > cin.getline(buffer, sizeof buffer); // Read an input line
> > eatspaces(buffer); // Remove blanks from input
> >
> > if(!buffer[0]) // Empty line ends calculator
> > return 0;
> >
> > cout << "\t= " << expr(buffer) // Output value of expression
> > << endl << endl;
> > }
> > }
> >
> >
> > // Function to eliminate blanks from a string
> > void eatspaces(char* str)
> > {
> > int i=0; // 'Copy to' index to string
> > int j=0; // 'Copy from' index to string
> >
> > while((*(str+i) = *(str+j++)) != '\0') // Loop while character
> > // copied is not \0
> > if(*(str+i) != ' ') // Increment i as long as
> > i++; // character is not a blank
> > return;
> > }
> >
> >
> > // Function to evaluate an arithmetic expression
> > double expr(char* str)
> > {
> > double value = 0; // Store result here
> > int index = 0; // Keeps track of current character[/color][/color]
position[color=blue][color=green]
> >
> > value = term(str, index); // Get first term
> >
> > for(;;) // Infinite loop, all exits inside
> > {
> > switch(*(str+index++)) // Choose action based on current[/color][/color]
character[color=blue][color=green]
> > {
> > case '\0': // We're at the end of the string
> > return value; // so return what we have got
> >
> > case '+': // + found so add in the
> > value += term(str, index); // next term
> > break;
> >
> > case '-': // - found so subtract
> > value -= term(str, index); // the next term
> > break;
> >
> > default: // If we reach here the string
> > cout << endl // is junk
> > << "Arrrgh!*#!! There's an error"
> > << endl;
> > exit(1);
> > }
> > }
> > }
> >
> >
> > // Function to get the value of a term
> > double term(char* str, int& index)
> > {
> > double value = 0; // Somewhere to accumulate the result
> >
> > value = number(str, index); // Get the first number in the term
> >
> > // Loop as long as we have a good operator
> > while((*(str+index)=='*')||(*(str+index)=='/'))
> > {
> >
> > if(*(str+index)=='*') // If it's multiply,
> > value *= number(str, ++index); // multiply by next number
> >
> > if(*(str+index)=='/') // If it's divide,
> > value /= number(str, ++index); // divide by next number
> > }
> > return value; // We've finished, so return what we've got
> > }
> >
> >
> > // Function to recognize an expression in parentheses
> > // or a number in a string
> > double number(char* str, int& index)
> > {
> > double value = 0.0; // Store the resulting value
> >
> > if(*(str+index) == '(') // Start of parentheses
> > {
> > char* psubstr = 0; // Pointer for substring
> > psubstr = extract(str, ++index); // Extract substring in[/color][/color]
brackets -[color=blue][color=green]
> > Memory is allocated in extract()
> > value = expr(psubstr); // Get the value of the substring
> > delete[]psubstr; // Clean up the free store -[/color]
> actually[color=green]
> > deleting Memory is allocated in extract()
> > return value; // Return substring value
> > }
> >
> > while(isdigit(*(str+index))) // Loop accumulating leading digits
> > value=10*value + (*(str+index++) - 48);
> >
> > // Not a digit when we get to here
> > if(*(str+index)!='.') // so check for decimal point
> > return value; // and if not, return value
> >
> > double factor = 1.0; // Factor for decimal places
> > while(isdigit(*(str+(++index)))) // Loop as long as we have digits
> > {
> > factor *= 0.1; // Decrease factor by factor of 10
> > value=value + (*(str+index)-48)*factor; // Add decimal place
> > }
> >
> > return value; // On loop exit we are done
> > }
> >
> >
> > // Function to extract a substring between parentheses
> > // (requires string)
> > char* extract(char* str, int& index)
> > {
> > char buffer[MAX]; // Temporary space for substring
> > char* pstr=0; // Pointer to new string for return
> > int numL = 0; // Count of left parentheses found
> > int bufindex = index; // Save starting value for index
> >
> > do
> > {
> > buffer[index-bufindex] = *(str+index);
> > switch(buffer[index-bufindex])
> > {
> > case ')':
> > if(numL==0)
> > {
> > buffer[index-bufindex] = '\0'; // Replace ')' with '\0'
> > ++index;
> > pstr = new char[index-bufindex];
> > if(!pstr)
> > {
> > cout << "Memory allocation failed,"
> > << " program terminated.";
> > exit(1);
> > }
> > strcpy(pstr,buffer); // Copy substring to new memory
> > return pstr; // Return substring in new memory
> > }
> > else
> > numL--; // Reduce count of '(' to be matched
> > break;
> >
> > case '(':
> > numL++; // Increase count of '(' to be matched
> > break;
> > }
> > } while(*(str+index++) != '\0');// Loop - don't overrun end of string
> >
> > cout << "Ran off the end of the expression, must be bad input."
> > << endl;
> > exit(1);
> > return pstr;
> > }[/color]
>
> expr() calls term()
>
> term() calls number()
>
> number() expr()
>
> There is 'indirect' recursion of 'expr()'.
>
> Finally, I recommend you find a better book to learn C++.
> This code seems to be a mish-mash mixture of "C-style"
> and C++ code. IMO the author is doing you an extreme
> disservice by not showing you how to use the std::string
> type, which is much safer and easier to use than arrays
> of characters (I see the code does #include <string>,
> but doesn't make use of any of its symbols -- very
> poor practice, which can easily confuse the novice.).
>
> Note that "Visual C++ 6" is not a language, but a Microsoft
> product (which btw is capable of handling a much more modern
> form of C++, the standard library containers, etc.).
>
> See
www.accu.org for book reviews.
>
> -Mike
>
>[/color]
The program is supposed to calculate a basic arithmetic expression such as:
2.5+8.67*2.23/1.7
or
(59.68*1.25+7.4/6.7456)-((2.56/1.39+7.89)*299.72)
Below is a paste of using the program after entering the 2 expressions
above:
Welcome to your friendly calculator.
Enter an expression, or an empty line to quit.
2.5+8.67*2.23/1.7
= 13.873
(59.68*1.25+7.4/6.7456)-((2.56/1.39+7.89)*299.72)
= -2841.1