ISBN 1-861000-88-X
I'm confused about these references to the usage of recursion pertaining to
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 be
taken care of automatically. Recursion wins again.
On page 237 in the last sentence of the first paragraph: "This is really
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 due
to the amazing power of recursion."
I had thought recursion is when a function calls itself, but I can't seem to
find this in the source code. If it's there, where ?
Another point, the error checking in the Ex6_08A program on pg 236 fails to
catch these user entry errors:
6++3
2**4
6****7
9/////2
7-----5
etc.
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 evaluated
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 position
value = term(str, index); // Get first term
for(;;) // Infinite loop, all exits inside
{
switch(*(str+index++)) // Choose action based on current character
{
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 brackets -
Memory is allocated in extract()
value = expr(psubstr); // Get the value of the substring
delete[]psubstr; // Clean up the free store - actually
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;
} 3 1149
"dave" <da*****@mindspring.com> wrote in message
news:uU*****************@newsread2.news.atl.earthl ink.net... ISBN 1-861000-88-X
I'm confused about these references to the usage of recursion pertaining
to 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 be taken care of automatically. Recursion wins again.
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. On page 237 in the last sentence of the first paragraph: "This is really 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
due to the amazing power of recursion."
Many people become enamored with recursion perhaps because
they find it somehow 'elegant'. But imo it's very often
abused. I had thought recursion is when a function calls itself,
Yes.
but I can't seem to find this in the source code. If it's there, where ?
See below (after the code). Another point, the error checking in the Ex6_08A program on pg 236 fails
to catch these user entry errors: 6++3 2**4 6****7 9/////2 7-----5 etc.
Well, fix it! :-) 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 evaluated
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 position
value = term(str, index); // Get first term
for(;;) // Infinite loop, all exits inside { switch(*(str+index++)) // Choose action based on current character { 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 brackets - Memory is allocated in extract() value = expr(psubstr); // Get the value of the substring delete[]psubstr; // Clean up the free store -
actually 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; }
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
On Thu, 01 Apr 2004 01:04:26 GMT in comp.lang.c++, "dave"
<da*****@mindspring.com> wrote, I had thought recursion is when a function calls itself,
Yes, but often not directly.
but I can't seem to find this in the source code. If it's there, where ?
expr() -> term() -> number() -> expr()
"Mike Wahler" <mk******@mkwahler.net> wrote in message
news:rs*****************@newsread2.news.pas.earthl ink.net... "dave" <da*****@mindspring.com> wrote in message news:uU*****************@newsread2.news.atl.earthl ink.net... ISBN 1-861000-88-X
I'm confused about these references to the usage of recursion pertaining to 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
be taken care of automatically. Recursion wins again.
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.
On page 237 in the last sentence of the first paragraph: "This is
really 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
due to the amazing power of recursion."
Many people become enamored with recursion perhaps because they find it somehow 'elegant'. But imo it's very often abused.
I had thought recursion is when a function calls itself,
Yes.
but I can't seem to find this in the source code. If it's there, where ?
See below (after the code).
Another point, the error checking in the Ex6_08A program on pg 236 fails
to catch these user entry errors: 6++3 2**4 6****7 9/////2 7-----5 etc.
Well, fix it! :-)
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
evaluated 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
position value = term(str, index); // Get first term
for(;;) // Infinite loop, all exits inside { switch(*(str+index++)) // Choose action based on current
character { 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
brackets - Memory is allocated in extract() value = expr(psubstr); // Get the value of the substring delete[]psubstr; // Clean up the free store -
actually 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; }
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
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 This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: coinjo |
last post by:
Which is the best C++ book for beginners?
|
by: James Thompson |
last post by:
I'm sure this question has been asked a hundred times. I did a google
search and found some older post and some mixed reviews. I am looking
for an updated opinion on which book is the best for...
|
by: Mike |
last post by:
Hi,
I am planning on purchasing VS2005 to learn C# very soon, and I need good
book recommendations. I realize this is a question that may be asked a lot,
but please consider my background:
I...
|
by: Sam |
last post by:
Hi All
I don't know anything about C# and I'm planning to learn the language. Does
anyone know any good book out there that explains things well?
Any suggestion is greatly appreciated
...
|
by: Fie Fie Niles |
last post by:
I have been using Visual Basic 6 and ASP (Visual Interdev 6) for a few
years. I would like to learn VB.NET and ASP.NET.
If I study Visual Studio.NET, will it cover both ASP.NET and VB.NET ?
Based...
|
by: pp |
last post by:
Hi,
I want to buy a book for learning C#, do you have any ideas?
Tanks,
Paulo Praça
|
by: Dennis D. |
last post by:
Having problems converting Murach's Beginning Visual Basic.net (Prince) and
Microsoft Press' Programming Visual Basic.net (Balena) examples for use in
VB.net 2005 Express. The VS conversion wizard...
|
by: www.douglassdavis.com |
last post by:
I'm looking for advice here, and I would really appreciate it if you
could help.
Is there a VB 2005 book that you like and would recommend (and why)?
Would you consider it good for...
|
by: Jon Skeet [C# MVP] |
last post by:
I'm looking to write a C# book fairly soon, and the publisher I've
approached wants me to do a bit of market research to find out what
people like and don't like in this kind of book.
I've read...
|
by: AndrewMcLellan |
last post by:
Hello there guys,
So yeah, I'm looking for an easy book to beginning ASP.NET 3.5 with C#. I want to start building websites in ASP.NET and will be doing it in university also so looking for an...
|
by: ryjfgjl |
last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
|
by: emmanuelkatto |
last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud.
Please let me know.
Thanks!
Emmanuel
|
by: BarryA |
last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
|
by: nemocccc |
last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
|
by: Hystou |
last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
|
by: Oralloy |
last post by:
Hello folks,
I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>".
The problem is that using the GNU compilers,...
|
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
|
by: Hystou |
last post by:
Overview:
Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
|
by: tracyyun |
last post by:
Dear forum friends,
With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
| |