C++ Primer Plus Chapter 7 Exercise 9

c plus plusChapter 7 ends with a short exercise on function pointers. The simplest way to complete this, which I provided in my source, is to create the two functions add() and calculate(), then call them in main() with a loop. The text mentions if you are feeling adventurous to include other functions in addition to add. For simplicities sake, I did the minimum requirement here. Finally,  we can put this chapter to rest. See my source below:

9. Design a function calculate() that takes two type double values and a pointer to a function that takes two double arguments and returns a double. The calculate() function should also be type double, and it should return the value that the pointed-to function calculates, using the double arguments to calculate(). For example, suppose you have this definition for the add() function: double add(double x, double y){return x + y}. Then, the function call in double q = calculate(2.5, 10.4, add); would cause calculate() to pass the values 2.5 and 10.4 to the add() function and then return the add() return value (12.9). Use these functions and at least one additional function in the add() mold in a program. The program should use a loop that allows the user to enter pairs of numbers. For each pair, use calculate() to invoke add() and at least one other function. If you are feeling adventurous, try creating an array of pointers to add()-style functions and use a loop to successively apply calculate() to a series of functions by using these pointers. Hint: Here’s how to declare such an array of three pointers: double (*pf[3])(double, double); You can initialize such an array by using the usual array initialization syntax and function names as addresses.

#include <iostream>

using namespace std;

double calculate(double x, double y, double (*pf)(double a, double b));
double add(double x, double y);

int main()
{
double x, y;
cout << "Enter two numbers (q to exit): ";
while(cin >> x >> y)
{
if(cin.fail())
break;
calculate(x, y, add);
cout << "The sum is: " << calculate(x, y, add) << "\n\n";
}
return 0;
}

double calculate(double x, double y, double (*pf)(double a, double b))
{
return pf(x, y);
}

double add(double x, double y)
{
return x + y;
}

C++ Primer Plus Chapter 7 Exercise 8

c plus plus Exercise 8 has us re-writing a skeleton program to fill in the missing functions. A combination of structs, pointers, and functions will complete this exercise. Comments describing where and what additions have been made are embedded in the code. See my solution below:

8. This exercise provides practice in writing functions dealing with arrays and structures. The following is a program skeleton. Complete it by providing the described functions:


#include <iostream>

using namespace std;
const int SLEN = 30;
struct student {
char fullname[SLEN];
char hobby[SLEN];
int ooplevel;
};

int getinfo(student pa[], int n);
void display1(student st);
void display2(const student * ps);
void display3(const student pa[], int n);

int main(){
cout << "Enter class size: ";
int class_size;
cin >> class_size;
while (cin.get() != '\n')
continue;
student * ptr_stu = new student[class_size];
int entered = getinfo(ptr_stu, class_size);

for (int i = 0; i < entered; i++) {
display1(ptr_stu[i]);
display2(&ptr_stu[i]);
}
display3(ptr_stu, entered);
delete [] ptr_stu;
cout << "Done\n";

return 0;
}

// getinfo() has two arguments: a pointer to the first element of
// an array of student structures and an int representing the
// number of elements of the array. The function solicits and
// stores data about students. It terminates input upon filling
// the array or upon encountering a blank line for the student
// name. The function returns the actual number of array elements
// filled.
int getinfo(student pa[], int n)
{
int i;
for(i = 0; i < n; i++)
{
cout << "Student Number: " << (i+1) << "\n";
cout << "Student's Name: ";
cin.getline(pa[i].fullname, SLEN);

cout << "Enter students hobby: ";
cin.getline(pa[i].hobby, SLEN);

cout << "Enter students OOP level: ";
cin >> pa[i].ooplevel;
cin.get();
}
return i;
}

// display1() takes a student structure as an argument
// and displays its contents
void display1(student st)
{
cout << "\n=============Display 1================\n";
cout << "Student name: " << st.fullname << "\n";
cout << "Hobby: " <<  st.hobby << "\n";
cout << "OOP Level: " << st.ooplevel << "\n";
cout << "=============End Display 1==============\n";
}

// display2() takes the address of student structure as an
// argument and displays the structure's contents
void display2(const student * ps)
{
cout << "\n============Display 2================\n";
cout << "Students Name: " << ps->fullname << "\n";
cout << "Hobby: " << ps->hobby << "\n";
cout << "OOP Level" << ps->ooplevel << "\n";
cout << "==========End Display 2================\n";
}

// display3() takes the address of the first element of an array
// of student structures and the number of array elements as
// arguments and displays the contents of the structures
void display3(const student pa[], int n)
{
for(int i = 0; i < n; i++)
{
cout << "\n============Display 3================\n";
cout << "Student: " << (i+1) << "\n";
cout << "Fullname: " << pa[i].fullname << "\n";
cout << "OOP Level: " << pa[i].ooplevel << "\n";
cout << "=============End Display 3============\n";
}
}

C++ Primer Plus Chapter 7 Exercise 7

c plus plus

This exercise makes use heavier use of pointers then what we have been doing. However, much of this program can be pulled from listing 7.7 and around that part of the chapter. See source below.

Redo Listing 7.7, modifying the three array-handling functions to each use two pointer parameters to represent a range. The fill_array() function, instead of returning the actual number of items read, should return a pointer to the location after the last location filled; the other functions can use this pointer as the second argument to identify the end of the data.

#include <iostream>

using namespace std;

const int Max = 5;

// function prototypes
double * fill_array(double *first, double *last);
void show_array(const double *first, const double *last);
void revalue(double *first, double *last, double factor);

int main()
{
double properties[Max];
double * last;

last = fill_array(properties, properties+Max);
show_array(properties, last);

cout << "Enter revaluation factor: ";
double factor;
cin >> factor;

revalue(properties, last, factor);
show_array(properties, last);
cout << "Done.\n";

return 0;
}

double *fill_array(double *first, double *last)
{
double temp;
double *pt;
int i=0;
for (pt = first; pt != last; pt++, i++)
{
cout << "Enter value #" << (i + 1) << ": ";
cin >> temp;
if (!cin) // bad input
{
cin.clear();
while (cin.get() != '\n')
continue;
cout << "Bad input; input process terminated.\n";
break;
}
else if (temp < 0) // signal to terminate
break;
*pt = temp;
}
return pt;
}

void show_array(const double *first, const double *last)
{
const double *pt;
int i=0;
for (pt = first; pt != last; pt++, i++)
{
cout << "Property #" << (i + 1) << ": $ \n";
cout << *pt;
}
}

void revalue(double *first, double *last, double factor)
{
double *pt;
for (pt = first; pt != last; pt++)
*pt *= factor;
}

C++ Primer Plus Chapter 7 Exercise 6

c plus plusExercise 6 of chapter 7 is not so bad because the first two functions are given to us in the text. However, you do need to do some thinking as to how to reverse an array. There are a few ways to do this. One would be to implement an XOR type algorithm. Another would be to use reverse() from the std library, and then you can do it the way I have done it which is work through the array by starting on the ends. The way I have done it is one of the most common ways to solve this problem and is good to know as it is sometimes used as a skill assessment on programming interviews. See source below.

Write a program that uses the following functions:
Fill_array() takes as arguments the name of an array of double values and an array
size. It prompts the user to enter double values to be entered in the array. It ceases taking
input when the array is full or when the user enters non-numeric input, and it
returns the actual number of entries.
Show_array() takes as arguments the name of an array of double values and an array
size and displays the contents of the array.
Reverse_array() takes as arguments the name of an array of double values and an
array size and reverses the order of the values stored in the array.
The program should use these functions to fill an array, show the array, reverse the array,
show the array, reverse all but the first and last elements of the array, and then show the
array.

#include <iostream>

using namespace std;

const int Max = 5;

int fill_array(double ar[], int limit);
 void show_array(const double ar[], int n);
 void reverse_array(double ar[], int n);

int main()
 {
 double properties[Max];
 int size = fill_array(properties, Max);
 cout << endl;
 show_array(properties, size);
 cout << endl;
 reverse_array(properties, size);
 show_array(properties, size);
 cout << endl;
 reverse_array(properties + 1, size -2);
 show_array(properties, size);
 return 0;
 }

int fill_array(double ar[], int limit)
 {
 double temp;
 int i;
 for(i = 0; i < limit; i++)
 {
 cout << "Enter value #" << (i + 1) << ": ";
 cin >> temp;
 if(!cin)
 {
 cin.clear();
 while(cin.get() != '\n')
 continue;
 cout << "Bad input; input process terminated" << endl;
 break;
 }
 else if(temp < 0)
 break;
 ar[i] = temp;
 }
 return i;
 }

void show_array(const double ar[], int n)
 {
 for (int i = 0; i < n; i++)
 {
 cout << "Property #" << (i + 1) << ": ";
 cout << ar[i] << endl;
 }
 }

void reverse_array(double ar[], int n)
 {
 double temp;
 for(int i = 0; i < n/2; i++)
 {
 temp = ar[i];
 ar[i] = ar[n - i - 1];
 ar[n - i - 1] = temp;
 }
 }

Note: for the sake of the solution. fill_array() could be stripped of the error handling code to make this easier to read.

C++ Primer Plus Chapter 7 Exercise 5

c plus plusTo understand recursion, one must understand recursion.

Define a recursive function that takes an integer argument and returns the factorial of that argument. Recall that 3 factorial, written 3!, equals 3 × 2!, and so on, with 0! defined as 1. In general, if n is greater than zero, n! = n * (n – 1)!. Test your function in a program that uses a loop to allow the user to enter various values for which the program reports the factorial.

#include <iostream>

using namespace std;

int factorial(int number);

int main()
{
    int number;
    while(number != -1)
    {
        cout << "Enter a number to find it's factorial (q to quit): ";
        cin >> number;
        if(!cin.good())
            break;
        else
        {
            int factor;
            factor = factorial(number);
            cout << "Factorial " << number << " is " << factor << endl;
        }
    }
    return 0;
}

int factorial(int number)
{
    if(number == 0)
        return 1;
    return number * factorial(number - 1);
}

C++ Primer Plus Chapter 7 Exercise 4

c plus plusThe trick to this program is understanding what is it asking and getting it to work as it wants. In my solution I created a second function that holds all the numbers plus the probability function within it. I think this is one of the quickest solution to this exercise. The output is truncated to that of a long int, as I think the book format is quite ugly. Another way I had though of doing this originally was to calculate the odds of 1 in 47, store it. Calculate the 1 in 27 odds, store it, then find the product of those all in their own functions. That idea seemed clumsy when coding it and all roads were pointing to the solution provided for me.

Many state lotteries use a variation of the simple lottery portrayed by Listing 7.4. In
these variations you choose several numbers from one set and call them the field numbers.
For example, you might select 5 numbers from the field of 1–47). You also pick a
single number (called a mega number or a power ball, etc.) from a second range, such as
1–27. To win the grand prize, you have to guess all the picks correctly. The chance of
winning is the product of the probability of picking all the field numbers times the probability
of picking the mega number. For instance, the probability of winning the example
described here is the product of the probability of picking 5 out of 47 correctly times the
probability of picking 1 out of 27 correctly. Modify Listing 7.4 to calculate the probability
of winning this kind of lottery.

#include <iostream>

using namespace std;

// Note: some implementations require double instead of long double
long double probability(unsigned numbers, unsigned picks);
long int TotalOdds(int, int, int, int, long double(*p)(unsigned, unsigned));

int main()
{
cout << "Welcome to the Powerball!\n";
cout << "Odds of winning are one in " << TotalOdds(47, 5, 27, 1, probability);
cout << "\nThanks for playing!" << endl;

return 0;
}
// the following function calculates the probability of picking picks
// numbers correctly from numbers choices
long double probability(unsigned numbers, unsigned picks)
{
long double result = 1.0; // here come some local variables
long double n;
unsigned p;
for (n = numbers, p = picks; p > 0; n--, p--)
result = result * n / p;
return result;
}

long int TotalOdds(int FirstSet, int x, int PowerBall, int y, long double(*p)(unsigned, unsigned))
{
long double odds;
odds = p(FirstSet, x)*p(PowerBall, y);
return odds;
}

C++ Primer Plus Chapter 7 Exercise 3

c plus plusAfter a bit of a break, I am ready to continue these exercises as well as put out some other things I have been working on.  Chapter 7 exercise 3 wants us to create two functions using a structs given values, then use those functions and the struct in a program. Here is my solution to this problem:

3. Here is a structure declaration:
struct box
{
char maker[40];
float height;
float width;
float length;
float volume;
};
a. Write a function that passes a box structure by value and that displays the value of
each member.
b. Write a function that passes the address of a box structure and that sets the volume
member to the product of the other three dimensions.
c. Write a simple program that uses these two functions.

 #include <iostream>

using namespace std;

struct box
{
char maker[40];
float height;
float width;
float length;
float volume;
};

void showValue(box);
void setVolume(box*);

int main()
{
box toyBox = {"Elf", 2.5, 3.3, 5.0, 0};
showValue(toyBox);
setVolume(&toyBox);
cout << "\n\nWith volume calculated: \n";
showValue(toyBox);

return 0;
}

void showValue(box ourStruct)
{
cout << "Struct details\n";
cout << "Struct maker: " << ourStruct.maker << endl;
cout << "Struct height: " << ourStruct.height << endl;
cout << "Struct width: " << ourStruct.width << endl;
cout << "Struct length: " << ourStruct.length << endl;
cout << "Struct volume: " << ourStruct.volume << endl;
}

void setVolume(box* ourStruct)
{
ourStruct->volume = ourStruct->height * ourStruct->width * ourStruct->length;
}
 

C++ Primer Plus Chapter 7 Exercise 2

c plus plusExercise 2 is a good lesson in functions. You will be forced to use a function for every requirement of the program. In addition, you will have to be inventive with how you terminate the program early and still calculate a running average. See my source below:
2. Write a program that asks the user to enter up to 10 golf scores, which are to be stored
in an array. You should provide a means for the user to terminate input prior to entering
10 scores. The program should display all the scores on one line and report the average
score. Handle input, display, and the average calculation with three separate array-
processing functions.

#include <iostream>

const int maxSize = 10;

// Prototypes
int input(int scores[], int arSize);
double avg(int scores[], int arSize);
void display(int scores[], int arSize);

int main()
{
int scores[maxSize];
int arSize = input(scores, maxSize);
display(scores, arSize);
std::cout << "Average score: " << avg(scores, arSize);
return 0;
}

int input(int scores[], int arSize)
{
double score;
int count = 0;
std::cout << "Enter up to " << maxSize << " scores (press -1 to terminate)\n"; // Loop up to 10 times
for(int i = 0; i < maxSize; i++) // Loop until maxSize
{
std::cout << "Enter Score #" << (i + 1) << ": ";
std::cin >> score;
if(score > 0)
{
scores[i] = score; // assign score to score[i]
count++;
}
else
break;

}
return count; // return something sice fucntion is not void.

}

double avg(int scores[], int arSize)
{
double total = 0;
for(int i = 0; i < arSize; i++) // Loop as many times as was actually inputted
{
total += scores[i];
}
return total/arSize;
}

void display(int scores[], int arSize)
{
std::cout << "Scores: ";
for(int i = 0; i < arSize; i++) // Loop as many times as was actually inputted
{
std::cout << scores[i] << " "; // Print to one line
}
}

C++ Primer Plus Chapter 7 Exercise 1

c plus plusChapter 7 kicks off with a fairly painless reintroduction into functions. We computer harmonic mean for a number pair. There are probably a few ways to do this, but they should all be very similar. Take in two numbers, store them if you like as I did, check if they are zero’s, and if not compute the harmonic mean by way of a function. Check out my source below:

1. Write a program that repeatedly asks the user to enter pairs of numbers until at least one
of the pair is 0. For each pair, the program should use a function to calculate the har-
monic mean of the numbers. The function should return the answer to main(), which
should report the result. The harmonic mean of the numbers is the inverse of the aver-
age of the inverses and can be calculated as follows:
harmonic mean = 2.0 × x × y / (x + y)

#include <iostream>

using namespace std;

float Hmean(int x, int y);

int main()
{
int myArray[2];

cout << "Please enter pairs of numbers: " << endl;
cin >> myArray[0] >> myArray[1];

if(myArray[0] == 0 || myArray[1] == 0)
{
cout << "You have entered a pair matching zero" << endl;
cout << "Exiting..." << endl;
}
else
{
cout << "The Harmonic mean of " << myArray[0] << " and "
<< myArray[1] << " is " << Hmean(myArray[0],myArray[1]);
}
return 0;
}

float Hmean(int x, int y)
{
float calc = 2.0 * x * y / (x + y);

return calc;
}

C++ Primer Plus Chapter 6 Exercise 9

c++IconThe end of chapter 9 concludes with a fairly hefty compilation of some things you have learned thus far. You probably could have simply made a program that grabbed text from a file, but im sure you would still want to associate it with a struct like we have already done. The majority of this program will stay the same as exercise 6 except a couple of additions; one being we create a file stream named “inFile”. We then associate it with a hard-coded file “contrib.txt”, that has our struct info. Then, we check for a file opening error, see if the first line is an integer, and begin grabbing data from the file. This time I use the “new” keyword and make use of the atoi() function to make all this happen. Examine my source to see how I worked through this one:

9. Do Programming Exercise 6, but modify it to get information from a file. The first item
in the file should be the number of contributors, and the rest of the file should consist of
pairs of lines, with the first line of each pair being a contributor’s name and the second
line being a contribution. That is, the file should look like this:
4
Sam Stone
2000
Freida Flass
100500
Tammy Tubbs
5000
Rich Raptor
55000

#include <iostream>
#include <string>
#include <fstream>
#include <cstdlib>

using namespace std;

struct contrib
{
string name;
double amount;
};

int main()
{
// Create input stream
ifstream inFile;
inFile.open("contrib.txt");

// faile-safe
if (!inFile.is_open())
{
cout << "Failed to open: " << inFile << endl;
exit(EXIT_FAILURE);
}

int numDonors = 0;
int patrons = 0;
int grandPatrons = 0;
char lineOne;

cout << "Society for the Preservation of Rightful Influence" << "\n\n";
cout << "Reading File...\n";

(inFile >> lineOne).get();
if(!isdigit(lineOne))
{
cout << "Number of donors not found\n";
return 2;
}
else
cout << "The number of donors is: " << lineOne << "\n\n";

numDonors = atoi(&lineOne);

contrib *society = new contrib[numDonors];

// Gather names and amounts
for(int i = 0; i < numDonors; i++)
{
getline(inFile, society[i].name); // getline to grab names
cout << "Donor # " << (i+1) << " " << society[i].name << endl;
(inFile >> society[i].amount).get();
/*inFile >> society[i].amount;*/
cout << "Amount: " << (i+1) << society[i].amount<< endl;
}

cout << "\n";
// Display donors over 10000
cout << "Grand Patrons: \n";
for(int x = 0; x < numDonors; x++)
{
if(society[x].amount >= 10000)
{
cout << society[x].name << " Donated: "
<< "$ " << society[x].amount << "\n";
grandPatrons = 1;
}
}
if(grandPatrons == 0)
cout << "none\n";

cout << "\n";

// Display all other patrons

cout << "Patrons list: \n";
for(int y = 0; y < numDonors; y++)
{
if(society[y].amount < 10000)
{
cout << society[y].name << " Donated: "
<< "$ " << society[y].amount << "\n";
patrons = 1;
}
}
if(patrons == 0)
cout << "none\n";
delete [] society;

if (inFile.eof())
cout << "End of file reached.\n";
else if (inFile.fail())
cout << "Input terminated by data mismatch.\n";

// free memory
inFile.close();

return 0;
}