Google
 

Monday, January 10, 2011

C++ Primer, Fourth Edition Notes Chapter 7. Exercise

Exercise 7.1:

What is the difference between a parameter and an argument?

Exercise 7.2:

Indicate which of the following functions are in error and why. Suggest how you might correct the problems.

     (a) int f() {
string s;
// ...
return s;
}
(b) f2(int i) { /* ... */ }
(c) int calc(int v1, int v1) /* ... */ }
(d) double square(double x) return x * x;

Exercise 7.3:

Write a program to take two int parameters and generate the result of raising the first parameter to the power of the second. Write a program to call your function passing it two ints. Verify the result.

Exercise 7.4:

Write a program to return the absolute value of its parameter.

// EXE-7.2.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <string>
#include <cmath>

using namespace std;

int main(int argc, _TCHAR* argv[])
{
//Exercise 7.2: Indicate which of the following functions are in error and why. Suggest how you might correct the problems.

// (a) int f() {
// string s;
// // ...
// return s;
//}
// should return the int type value
//(b) f2(int i) { /* ... */ }
// should difine the return type
//(c) int calc(int v1, int v1) /* ... */ }
// should add the start block '{'
//(d) double square(double x) return x * x;
// should return the double type value

// Exercise 7.3:
// Write a program to take two int parameters and generate the result of raising the first parameter
// to the power of the second. Write a program to call your function passing it two ints. Verify the result.

long int power(int base,int exponent);
cout << "Please input two integers:\n";
int base(0), exponent(0);
cin >> base >> exponent;
cout << base << "'s power " << exponent << " is " << power(base,exponent) << endl;

int getArgument(int arg);
//Exercise 7.4: Write a program to return the absolute value of its parameter.
int param(0);
cin >> param;
cout << "The parameter is " << getArgument(param) << endl;

int i;
cin >> i;

return 0;
}

int getArgument(int arg)
{
return arg;
}
// How to implement the power efficient?
long int power(int base, int exponent)
{
long int result = 1;
while(exponent--!= 0)
{
result *= base;
}
return result;

//return exp(exponent * log((double)base));
}

Exercise 7.5:

Write a function that takes an int and a pointer to an int and returns the larger of the int value of the value to which the pointer points. What type should you use for the pointer?

// Exercise 7.5.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <string>

using namespace std;

int getLarger(int a, int *b);

int main(int argc, _TCHAR* argv[])
{
cout << "Please input two integers:\n";

int a(0), *b = new int();
cin >> a >> *b;
cout << "The larger is " << getLarger(a,b) << endl;

int i;
cin >> i;

return 0;
}
int getLarger(int a, int *b)
{
return (a > *b ? a : *b );
}

Exercise 7.6:

Write a function to swap the values pointed to by two pointers to int. Test the function by calling it and printing the swapped values.

// Exercise 7.6.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <string>
#include <iostream>

using namespace std;

int main(int argc, _TCHAR* argv[])
{
cout << "Please input two integers:\n";
int a(0), b(0);
cin >> a >> b;
cout << "Before swap:"
<< " a= " << a
<< " b= " << b << endl;
// here call the swap by swap(a, b); not swap(&a, &b);
swap(a, b);
cout << "After swap:"
<< " a= " << a
<< " b= " << b << endl;

int i;
cin >> i;

return 0;
}

void swap(int *a, int *b)
{
int tmp = *a;
*a = *b;
*b = tmp;
}

Exercise 7.7:

Explain the difference in the following two parameter declarations:

     void f(T);
void f(T&);
       void f(T);
// pass parameter as non reference
void f(T&);
// pass parameter as reference

Exercise 7.8:

Give an example of when a parameter should be a reference type. Give an example of when a parameter should not be a reference.

// Exercise 7.8.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>

using namespace std;

void swap(int &a, int &b);
void print(int a, int b, string strMark);

int main(int argc, _TCHAR* argv[])
{
cout << "Please input two integers:\n";
int a(0),b(0);
cin >> a >> b;

print(a,b,"Before");
//Attention: call swap as swap(a,b);, not swap(&a,&b);
swap(a,b);
print(a,b,"After ");

int i;
cin >> i;

return 0;
}

// should use reference
void swap(int &a, int &b)
{
int tmp = a;
a = b;
b = tmp;
}
// print out
void print(int a, int b, string strMark)
{
cout << strMark << " Swap:"
<< " a=" << a
<< " b=" << b << endl;
}

Exercise 7.9:

Change the declaration of occurs in the parameter list of find_val (defined on page 234) to be a nonreference argument type and rerun the program. How does the behavior of the program change?

//The caller can’t get the occurs value from the callee.

Exercise 7.10:

The following program, although legal, is less useful than it might be. Identify and correct the limitation on this program:

     bool test(string& s) { return s.empty(); }

bool test(const string s) 
{
return s.empty();
}

Exercise 7.11:

When should reference parameters be const? What problems might arise if we make a parameter a plain reference when it could be a const reference?

// the parameter will not be changed by callee, then the parameter should be const


// if the parameter is reference which should be const, the function’s flexible will be limited.


Exercise 7.12:

When would you use a parameter that is a pointer? When would you use a parameter that is a reference? Explain the advantages and disadvantages of each.

To use as pointer, when the parameters will be changed and it can’t be copied.

To use as reference, when the parameters will be changed. Easy to control and use.

Exercise 7.13:

Write a program to calculate the sum of the elements in an array. Write the function three times, each one using a different approach to managing the array bounds.

// Exercise 7.13.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <string>

using namespace std;

int sumWithSize( int *array, int size);
int sumWithStartEndPointer(int *start, int *end);
int sumWithEndMark(int *array, int endMark);

int main(int argc, _TCHAR* argv[])
{
int *p = new int[100]();
for (int i = 0; i < 100 ; ++i)
{
p[i] = i % 10;
}
cout << "Sum is " << sumWithSize(p,100) << endl;
cout << "Sum is " << sumWithStartEndPointer(p,p + 100) << endl;
p[99] = -1;
cout << "Sum is " << sumWithEndMark(p,-1);

// release dinamic array memory by delete [] p, not delete p;
delete[] p;
//delete p;
p = 0;

int i ;
cin >> i;

return 0;
}

int sumWithSize( int *array, int size)
{
int result(0);
for (int i = 0; i < size; ++i)
{
result += *( array + i);
}
return result;
}
int sumWithStartEndPointer(int *start, int *end)
{
int result(0);
while( start != end)
{
result += *start++;
//start++
}
return result;
}

int sumWithEndMark(int *array, int endMark)
{
int result(0);
while(*array != endMark)
{
result += *array++;
}
return result;
}

Exercise 7.14:

Write a program to sum the elements in a vector<double>.

// Exercise 7.14.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
using namespace std;

long double sum(vector<double>::const_iterator begin,vector<double>::const_iterator end);
int main(int argc, _TCHAR* argv[])
{
vector<double> *pVect = new vector<double>();
double i(10000.0);
while(i != 0)
(*pVect).push_back(i--);
cout << "The sum is " << sum((*pVect).begin(),(*pVect).end()) << endl;

delete pVect;
pVect = 0;

cin >> i;
return 0;
}

long double sum(vector<double>::const_iterator begin,vector<double>::const_iterator end)
{
long double result(0);
while(begin != end)
{
result += *begin++;
}
return result;
}

Exercise 7.15:

Write a main function that takes two values as arguments and print their sum.

// Exercise 7.15.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>

using namespace std;

int main(int argc, char* argv[])
{
int a(0), b(0);
//convert char array to integers
a = atoi(argv[1]);
b = atoi(argv[2]);
cout << argv[0] << endl;
cout << "The sum is " << a + b << endl;

int i;
cin >> i;

return 0;
}

Exercise 7.16:

Write a program that could accept the options presented in this section. Print the values of the arguments passed to

// Exercise 7.16.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <string>
#include <iostream>
#include <vector>

using namespace std;

int main(int argc, char* argv[])
{

// print out all arguments;
// the argc is the count of the arguments
while( argc != 0)
{
cout << argc << " th arg is " << argv[--argc] << endl;
}
int i(0);
cin >> i;

return 0;
}

Exercise 7.17:

When is it valid to return a reference? A const reference?

To return a reference to non local variable is valid.

For const reference, has the same condition.

Exercise 7.18:

What potential run-time problem does the following function have?

     string &processText() {
string text;
while (cin >> text) { /* ... */ }
// ....
return text;
}

The application will throw “bad alloc exception”, for the text available is cleared when the processText exits.

image 

// Exercise 7.18.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;

string &processText();
int main(int argc, _TCHAR* argv[])
{
string result = processText();

cout << result << endl;
int i;
cin >> i;
return 0;
}

string &processText()
{
string text;
while (!getline(cin,text)) {
}
return text;
}

Exercise 7.19:

Indicate whether the following program is legal. If so, explain what it does; if not, make it legal and then explain it:

     int &get(int *arry, int index) { return arry[index]; }
int main() {
int ia[10];
for (int i = 0; i != 10; ++i)
get(ia, i) = 0;
}

//set all array element as 0;

A natural way to solve this problem is recursively:

     // calculate val!, which is 1*2 *3 ... * val
int factorial(int val)
{
if (val > 1)
return factorial(val-1) * val;
return 1;
}
// calculate the valth factorial element value
// Exercise 7.19.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <string>
#include <iostream>

using namespace std;

int factorial(int val);
int &get(int *arry, int index) { return arry[index]; }
int main() {
int ia[10];
int i(10);
while(i!= 0)
{
cout << i << "th " << ia[--i] << endl;
}

for (int i = 0; i != 10; ++i)
get(ia, i) = 0;

int j(10);
while(j!= 0)
{
cout << j << "th " << ia[--j] << endl;
}

int f0(10);
cout << factorial(f0) << endl;

int k;
cin >> k;
return 0;
}

// calculate val!, which is 1*2 *3 ... * val
int factorial(int val)
{
if (val > 1)
return factorial(val-1) * val;
return 1;
}

Exercise 7.20:

Rewrite factorial as an iterative function.

 

Exercise 7.21:

What would happen if the stopping condition in factorial were:

     if (val != 0)

Exercise 7.22:

Write the prototypes for each of the following functions:



  1. A function named compare with two parameters that are references to a class named matrix and with a return value of type bool.



  2. A function named change_val that returns a vector<int> iterator and takes two parameters: one is an int and the other is an iterator for a vector<int>.


Hint: When you write these prototypes, use the name of the function as an indicator as to what the function does. How does this hint affect the types you use?

Exercise 7.23:

Given the following declarations, determine which calls are legal and which are illegal. For those that are illegal, explain why.

     double calc(double);
int count(const string &, char);
int sum(vector<int>::iterator, vector<int>::iterator, int);
vector<int> vec(10);

(a) calc(23.4, 55.1);
(b) count("abcda", 'a');
(c) calc(66);
(d) sum(vec.begin(), vec.end(), 3.8);

 


Exercise 7.24:

Which, if any, of the following declarations are errors? Why?

     (a) int ff(int a, int b = 0, int c = 0);
(b) char *init(int ht = 24, int wd, char bckgrnd);

Exercise 7.25:

Given the following function declarations and calls, which, if any, of the calls are illegal? Why? Which, if any, are legal but unlikely to match the programmer's intent? Why?

     // declarations
char *init(int ht, int wd = 80, char bckgrnd = ' ');

(a) init();
(b) init(24,10);
(c) init(14, '*');

Exercise 7.26:

Write a version of make_plural with a default argument of 's'. Use that version to print singular and plural versions of the words "success" and "failure".

 


Exercise 7.27:

Explain the differences between a parameter, a local variable and a static local variable. Give an example of a program in which each might be useful.

Exercise 7.28:

Write a function that returns 0 when it is first called and then generates numbers in sequence each time it is called again.

 


Exercise 7.29:

Which one of the following declarations and definitions would you put in a header? In a program text file? Explain why.

     (a) inline bool eq(const BigInt&, const BigInt&) {...}
(b) void putValues(int *arr, int size);

Exercise 7.30:

Rewrite the is Shorter function from page 235 as an inline function.

 


Exercise 7.31:

Write your own version of the Sales_item class, adding two new public members to read and write Sales_item objects. These functions should operate similarly to the input and output operators used in Chapter 1. Transactions should look like the ones defined in that chapter as well. Use this class to read and write a set of transactions.

Exercise 7.32:

Write a header file to contain your version of the Sales_item class. Use ordinary C++ conventions to name the header and any associated file needed to hold non-inline functions defined outside the class.

Exercise 7.33:

Add a member that adds two Sales_items. Use the revised class to reimplement your solution to the average price problem presented in Chapter 1.

 


Exercise 7.34:

Define a set of overloaded functions named error that would match the following calls:

     int index, upperBound;
char selectVal;
// ...
error("Subscript out of bounds: ", index, upperBound);
error("Division by zero");
error("Invalid selection", selectVal);

Exercise 7.35:

Explain the effect of the second declaration in each one of the following sets of declarations. Indicate which, if any, are illegal.

     (a) int calc(int, int);
int calc(const int, const int);

(b) int get();
double get();

(c) int *reset(int *);
double *reset(double *);

Exercise 7.36:

What is a candidate function? What is a viable function?

Exercise 7.37:

Given the declarations for f, determine whether the following calls are legal. For each call list the viable functions, if any. If the call is illegal, indicate whether there is no match or why the call is ambiguous. If the call is legal, indicate which function is the best match.

     (a) f(2.56, 42);
(b) f(42);
(c) f(42, 0);
(d) f(2.56, 3.14);

 


Exercise 7.38:

Given the following declarations,

     void manip(int, int);
double dobj;

what is the rank (Section 7.8.4, p. 272) of each conversion in the following calls?

     (a) manip('a', 'z');    (b) manip(55.4, dobj);

Exercise 7.39:

Explain the effect of the second declaration in each one of the following sets of declarations. Indicate which, if any, are illegal.

     (a) int calc(int, int);
int calc(const int&, const int&);

(b) int calc(char*, char*);
int calc(const char*, const char*);

(c) int calc(char*, char*);
int calc(char* const, char* const);

Exercise 7.40:

Is the following function call legal? If not, why is the call in error?

     enum Stat { Fail, Pass };
void test(Stat);
test(0);

No comments: