473,395 Members | 2,446 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

Book: 'Beginning Visual C++ 6' By Ivor Horton

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;
}
Jul 22 '05 #1
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
Jul 22 '05 #2
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()

Jul 22 '05 #3

"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

Jul 22 '05 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: coinjo | last post by:
Which is the best C++ book for beginners?
4
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...
4
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...
11
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 ...
12
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...
6
by: pp | last post by:
Hi, I want to buy a book for learning C#, do you have any ideas? Tanks, Paulo Praça
6
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...
11
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...
22
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...
3
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...
0
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...
0
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
0
BarryA
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...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
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...
0
Oralloy
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,...
0
jinu1996
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...
0
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...
0
tracyyun
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...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.