UCLA PIC 10B,  Problem Solving using C++

Summer 2001,

 

Instructor: Ivo Dinov, Asst. Prof. In Mathematics/Neurology

 

Midterm Exam Study Guide

 

Thursday, July 19, 2001, 9:30 AM, PPB # 2214

 

Multiple choice questions may have more than one correct answer. Give all correct answers. If an answer to a multiple choice question is in some sense only partially correct, an explanation should be worth points. True - False questions require an explanation.

 

I. Part One

 

1.     A string variable is the same thing as an  _ _ _ _ _   _ _   _ _ _ _ _ _ _ _ _ _.

 

2.     What is the length (maximum) of a string that can be placed in the string variable declared by the following declaration?  Explain.

 

char s[6];

 

3.      

a)     What does the \ do in the null character '\0' or the newline character '\n'?

b)    What happens if you use a \w in an output statement?

 

4.     Give a declaration of a string s that is initialized in the declaration to the string "Happy Face :) ".

 

5.     How many characters are in each of the following character and string constants:

a)  '\n'

b)  'n'

c)  "Mary"

d)  "M"

e)  "Mary\n"

 

6.     Give the values for each character given the following string variable declaration. If an entry in the array is not given a value by the declaration, mention this.

 

char my_message[12] = "Hi there";

 

7.     Declare a string named str capable of holding a string of length 10. Do not initialize it.

 

8.     Since character strings are just arrays of char, why does the text caution us not to confuse the following declaration and initialization?

 

char short_string[] = "abc";

char short_string[] = { 'a', 'b', 'c'};

 

9.     Given the declaration and initialization of the string variable:

 

char our_string[5] = "Hi";

 

Write a loop to assign 'X' to all positions to this string variable, keeping the length the same.

 

10.  Given the declaration of a string variable, where SIZE is a defined constant:

 

char our_string[SIZE];

 

The string variable our_string has been set in code not shown here. For correct string variables, the following loop reassigns all positions of our_string the value 'X', leaving the length the same as before.

 

index = 0;

while (our_string[index] != '\0')

{

our_string[index] = 'X';

index++;

}

 

a)     Explain how this can destroy the contents of memory beyond the end of the array.

 

b)    Modify this loop to protect against inadvertently changing memory beyond the end of the array.

 

11.  Write code using a library function to copy the string constant "Hello" into the string variable declared here. Be sure to #include the necessary header file to get the declaration of the function you use.

 

char a_string[10];

 

12.   What is the output from this code segment, if embedded in a correct program and executed? Explain.

 

#include <cstring>

  // whatever using directive that may be necessary

char a[10] = "Hello";

char b[10] = "Hi there";

 

if (strcmp( a, b ))

cout << "The strings are NOT the same";

else

cout << "The strings are the same";

cout << endl;

 

13.  Give declarations of char array variables of size 9 and 12. These declarations should initialize the arrays with the string constants "Hello" and "Hi there". Write code that outputs
"The strings are NOT the same" if the strings are different, and outputs
"The strings are the same" if the strings are the same.  Be sure to #include headers for any library function(s) you use.

 

14.  What dangers lurk in the use of functions declared in string? Give  an example.

 

15.  Describe the functions strlen, strcat, strcpy and strcmp. Give

a)     the arguments for each function

b)    the type of the return value for strlen and tell what this return value means.

c)     the type of the return value for strcmp and tell what this return value means.

d)    the action of strcpy

e)     the action of strcat

 

16.  Which of the following declarations are equivalent?

a)  char str[12] = "Ahoy!";

b)  char str[12] = { 'A', 'h', 'o', 'y','!', '\0'};

c)  char str[6] = "Ahoy!";

d)  char str[12] = { 'A', 'h', 'o', 'y','!'};

e)  char str[] = "Ahoy!";

 

17.  What string will be output when this code is run? (Assume, as always, that this code is embedded in a complete, correct program.)

 

char song[10] = "I did it ";

char franks_song[20];

strcpy ( franks_song, song );

strcat ( franks_song, "my way!");

cout << franks_song << endl;

 

18.  What is the problem (if any) with this code?

 

char to_mia[] = "Frank sang, \" ";

strcat( to_mia, "I get along without you very well.");

 

19.  Suppose the function strlen were not already implemented for you in the library. Write a function definition for strlen. Remember that strlen takes only one argument, const char source[], and returns an int.

 

20.  Complete the dialog below when this code is run. You are to assume it has been embedded in a complete correct program.

 

char a[10];

cout << "Enter a line of input. " << endl;

cin.getline( a, 10);

cout << a << "<END OF OUTPUT" << endl;

 

Dialog:

Enter a line of input.

Do be do, do be do!

 

21.  Explain the getline member of the istream class.

a)     give the arguments (we know about two). What do the arguments do?

b)    give an example

c)     describe the behavior, specifically with regard where the input stops.

 

22.  Assume that line has been declared to be an array of char of size 80. Assume further that the file variable in_stream has been connected to a file infile.dat. Give code to read a line of data (or as much as will fit into the string variable line) from the file infile.dat into the string variable line.

 

23.  Given the declarations:

 

char number1[] = "3456";

char number2[] = "3.456e-7";

int n1;

double n2;

 

Provide the necessary header #include, and give a code fragment to translate the string

a)     number1 into an int value and assign it to n1,

b)    number2 into a double value and assign it to n2,

 

24.  Consider the following code. Assume it is embedded in a complete and correct program and then executed:

 

char my_string[80] = "Enter a line of input\n";

cout << my_string;

cin.getline(my_string, 7);

cout << my_string << "<END OF OUTPUT" << endl;

 

If the dialog begins as follows, what is the output?

 

Enter a line of input:

May I get an ‘A’ in PIC10B.

 

25.  Declare a void function my_func that accepts an array declared as

 

int arr[10][25];

 

as one parameter. One other parameter is necessary. Give a function declaration (prototype) for this function. (Do not define it, you don't have enough information.)

 

26.  Write a code fragment that will prompt for and accept input to fill the array list (declared here) with 10 names typed in at the keyboard, assuming that the code you write is embedded in a correct, complete program.

 

char list[10][20];

 

27.  If the following code is embedded in a correct, complete program, it will fill the array list, declared here, with 10 names typed in at the keyboard.

 

char list[10][20];

int index;

cout << "Enter 10 names, one per line:" << endl;

for (index = 0; index < 10; index++ )

cin.getline(list[index], 20);

 

What code can be added to this code fragment to output to the screen the first letter of each name, one letter per line?

 

28.  Assume this code fragment is embedded in a complete, correct program.  What is the output from this code fragment?

 

int array[4][4];

int index1, index2;

for (index1 = 0; index1 < 4; index1++)

for (index2 = 0; index2 < 4; index2++)

array[index1][index2] = index2;

for (index1 = 0; index1 < 4; index1++)

{

for (index2 = 0; index2 < 4; index2++)

cout << array[index1][index2] << " ";

cout << endl;

}

 

29.  Given the three String objects declared here. Give code using the class String members, concatenate word1 and word2 and assign them to phrase.

 

a)  String phrase, word1( "Mama " ), word2("mia!");

 

30.  Given the two String class objects declared here. The following use of overloaded operator+ from the String class to concatenate word1 and a blank ' ' is legal. Explain how this can be, since ' ' is not a String object.

 

String phrase, word1( "PIC10B" );

phrase = word1 + " ";

 

31.  Given the String class object declared here and the input statement:

 

String word;

cin >> word;

 

With the following input, what is place in the String object word? Why?

 

Mary was a little girl.

 

32.  Write code using the String class members from the text to read into  a string variable word all the characters from the input

 

String word;

 

Input:

Mary was a little girl.

 

33.  Consider the following partial String class definition. There is enough provided here for you to give a definition of the default constructor for this class.

 

const int MAX_STRING_LENGTH = 100;

 

class String

{

public:

String();

// initializes the object to the empty string;

...

private:

char character[MAX_STRING_LENGTH];

int current_length;

};

 

34.  Complete the definition of the member function String::set_char as declared here:

 

const int MAX_STRING_LENGTH = 100;

 

class String

{

public:

String();

// initializes the object to the empty string;

 

void set_char( int position, char new_char);

// Precondition: 0 <= position <= length

// where length is the value of calling_object.length()

// Action: Changes the character in position to new_char

// Notes:

// 1) the first character is in position 0.

// 2) You can set position to current_length

// which is one beyond the end of the string, adding

// one character to the end of the string.

...

private:

char character[MAX_STRING_LENGTH];

int current_length;

};

 

35.  Declare an array of 20 String objects named list. Write a code fragment to prompt for and accept 20 names, one per line.

 

36.  Declare an array of 20 String objects named list. Write a code fragment to prompt for and accept 20 names, one per line, then write code that will write the same names to the screen.

 

37.   Explain the definition of the multi-dimensional array int myIntArray3D[300][100][200]; Order the indices fast-to-slow, elaborate on the very definition of a 3D array -  its meaning. If the address of the first element is in memory location 1000, compute the starting lication for the element myIntArray3D[1][25][15].

 

 

II. Part Two

1.     Explain the concept of pointer in C++. Describe for the fact that objects occupy more than one memory address, e.g., an int type takes 4bytes=32bits(all of which are separate addresses.

 

2.      Give a declaration of a pointer to a double named double_ptr.

 

3.     What unfortunate misinterpretation can occur with the following  declaration?

 

int* int_ptr1, int_ptr2;

 

4.     This declaration can be misinterpreted to mean that both of these variables are int pointers. They are not. Give declarations that correctly declare these as int pointers. Hint: there are three that I can think of, one of which uses a typedef.

 

int* int_ptr1, int_ptr2;

 

5.     This declaration can be misinterpreted to mean that both of these variables are int pointers.  Show how to use typedef to have a declaration of these two that does declare these as int pointers.

 

a)  int* int_ptr1, int_ptr2;

 

6.     What is the type of each of the identifiers in the following declarations?

 

int * p1, p2;

 

7.  Declare v to be an int, and p to be a pointer to int, initialized in the declaration to point to v.

 

8.     Explain how an address can be an integer, a pointer is an address, but an address is not an integer.  Hint: This has to do with abstraction and the C++ type system.

 

9.     Give at least 3 uses of the & operator/symbol.  State what the & is doing, and  name the use of the & that you present.

 

10.  Give at least 3 uses of the * operator. State what the * is doing, and  name the use of the * that you present.

 

11.  What output does the following code produce?

 

int a = 0;

int *p = &v1;

*p = 49;

cout << a << endl;

cout << *p << endl;

 

12.  Make several drawings to illustrate the effect of these successive assignments given here. In particular, do not make ONE drawing then change that drawing.

 

Draw boxes for all these variables. Put int values in the boxes, and draw arrows to represent the values of the pointers to heap memory.

 

What untoward thing happens when the last assignment of pointers is made?

 

int *p1 = new int;

int *p2 = new int;

*p1 = 120;

*p2 =  60;

*p1 = *p2;

p1 = p2;

 

13.  Describe the difference between the effect of the following two assignments in the last two lines:

 

int * p1;

int * p2;

// code goes here to give p1 and p2 legitimate values

*p1 = *p2

p1 = p2;

 

14.  Describe the action of the new operator. What does the operator new return? What are the indications of errors?

 

15.  Write a code fragment that allocates memory on the heap (free store) for a variable of type int, and checks for error.

 

16.  You have a program that allocates memory on the heap (free store). What operator returns that storage to the heap (free store) for reallocation?

 

17.  What is a dangling pointer problem? What is the danger of dangling pointers?  What can you do to protect yourself against dangling pointers?

 

18.  Write a definition for a type called IntPtr that will be the type for pointer variables that hold pointers to dynamic variables of type int.  Write a declaration for a pointer variable named my_ptr which is of type IntPtr. Create a dynamic variable for this pointer.

 

19.  Write a code fragment that creates a dynamic array of int, that reads the size into your code fragment. Continue with code to fill each array position with an int equal to the its array index.

 

20.  Given the following code fragment, give code that destroys the dynamic array variable  a.

 

typedef int* IntArrayPtr;

 

IntArrayPtr a;

int array_size;

cin >> array_size;

a = new int[ array_size ];

 

21.   Assume the following code fragment is embedded in a complete correct program. If there is not enough memory in the heap (free store), the call to new will fail.  Give code that checks for this failure, and in the event of a failure, writes an error message to the screen, then exits the program.

 

typedef int* IntArrayPtr;

 

IntArrayPtr a;

int array_size;

cin >> array_size;

a = new int[ array_size ];

 

22.  Write a typedef statement for a type name, CharArray, for pointer variables that will be used to point to dynamic arrays having base type char.

 

23.  Given the following code that creates a dynamic array.

 

int * value = new int[10];

 

Write code that fills this array with 10 numbers typed in at the keyboard.

 

24.  Given the definitions:

 

int a[10];

int * p = a;

 

Which of the following is correct?

 

a)  *p is the same variable as a[0]

b)  *(p + 2) is the same variable as a[2];

c)  p[3] is a legal index operation.

d)  a++; is a legal operation.

e)  p++; is a legal operation.

 

25.  Given the code, which is assumed to be embedded in a correct and complete program:

 

int array_size = 10;

int a[array_size];

int * p = a;

int i;

for (int i = 0; i < array_size; i++)

a[i] = i;

 

What is the output of the following code fragment?

 

for (int i = 0; i < array_size; i++)

cout << p[i] << " ";

cout << endl;

 

26.  Answer these questions about destructors.

a)     What is a destructor and what must the name of a destructor be?

b)    When is a destructor called?

c)     What does a destructor actually do?

d)    What should a destructor do?

 

e)      

27.  Answer these questions about copy constructors.

a)     What is a copy constructor? What must its name be?

b)    When is a copy constructor called?

c)     What does a copy constructor actually do?

d)    What should copy constructor do?

 

28.   

a)     If you do not provide a copy constructor, what happens when one is needed?

b)    If you do not provide an operator = overloading, what happens when one is needed?

c)     If you do not provide a destructor, what happens when one is needed?

 

29.  The following is the first line of the copy constructor definition for class StringVar. The identifier StringVar occurs three times. It means something slightly different each time. What does it mean in each of the three cases?

 

StringVar::StringVar( const StringVar& string_object)

 

30.  I want to overload the assignment operator, operator =. Can I make the operator= a friend of the class?

 

31.  Here is an attempt at defining operator = for the class StringVar that  has a bug when we try to assign a string to itself:

 

my_string = my_string;

 

Examine the code carefully and explain what the bug is.

 

void StringVar::operator= ( const StringVar & right )

{

delete [] value;

int new_length = strlen(right.value);

max_length = new_length;

value = new char [max_length+1];

if ( NULL == value )

{

cout << "error, insufficient memory " << endl;

exit(1);

}

for (int i = 0; i < new_length; i++)

value[i] = right.value[i];

value[new_length] = '\0';

}

 

III. Part Three

1.     Explain in your own words what recursion means (in connection with definitions of  ideas and as a programming technique.)

 

2.     Any function whose definition contains a call to the function being defined is called a _______________ function.

 

3.     True of False: A recursive function must not return a value.

 

4.     How does the computer keep track of all the calls to a recursive function?

 

5.     Give a general outline of a successful recursive function definition.

 

6.     Describe the stack memory (or data) structure. Give a four-word description of the stack discipline.

 

7.     Why might a recursive solution to a problem run slower than an iterative version that does the same thing?

 

8.     Iterative solutions are always possible. Why then, would we bother with recursive solutions to problems? What advantages do some recursive algorithms have over the iterative versions?

 

9.  Here is a recursive function. Write an iterative version of it. Hint: Be sure you get the number of copies of "Hip" right.

 

#include <iostream>

void rec_cheers( int n )

{

  using namespace std;

if ( 1 == n )

cout << "Hurray!" << endl;

else

{

cout << "Hip, ";

rec_cheers ( n - 1 );

}

}

 

10.  Here is an iterative function. Write a recursive function that does the same thing. Be sure you get right the number of times "Hip" is written. For this exercise you can ignore namespace issues.

 

void iter_cheers( int n )

{

for ( int i = 0; i < n-1; i++ ) // this is the tricky part!

{

cout << "Hip, ";

}

cout << "Hurray!" << endl;

}

11.  Write a recursive function that returns the sum of the members of an array of int numbers. Hint: For the recursive part, return the last element  +  the sum of the rest of the array. What should the base case be?

 

12.  Write a recursive void function that has one parameter which is a positive integer. When called, the function is to write its arguments to the screen backward: If the argument is 1234, the output should be.  4321.

 

13.  Write a recursive version of this iterative function:

 

int g( int n)

{

int h = 1;

int i = 0;

while ( i < n )

{

h = h * n;

h--;

}

return h;

}

 

 

14.  Here is a recursive function that is supposed to return the factorial.  Identify the line(s) with the logical error(s). Hint: This compiles and runs, and it computes something. What is it?

 

int fact( int n )                //a

{

int f = 1;                     //b

if ( 0 == n || 1 == n )  //c

return f;                   //d

else

{

f = fact(n - 1);            //f

f = (n-1) * f;              //g

return f;                   //h

}

}

 

15.  Give the three criteria for a correct value returning recursive function.

 

16.  Give the three criteria for a correct recursive void-function.

 

17.  In the binary search, if the array being searched has 32 elements in it, how many elements of the array must be examined to be certain that the array does not contain the key? What about 1024 elements? Note: the answer is the same regardless of whether the algorithm is recursive or iterative.

 

18.  Overloading and Recursion look to be similar. Both situations call functions with the same name.  Explain the difference.

 

19.  In the binary search, each pass (recursion or iteration) selects a subproblem of the original problem to solve. What fraction the array sent to an initial call is eliminated in the next iterative pass or recursive call?

 

20.  Give a pseudo-code description of the recursive binary search algorithm.

 

21.  In both the iterative and the recursive binary search, explain why the condition for halting the routine with the variable found assigned false is first > last.

 

22.  The form of recursion where the recursive call is the last statement executed by the function is called _ _ _ _ recursion.

 

23.  The part of a recursive function definition where that does not lead to the function calling itself is called the _ _ _ _ case or _ _ _ _ _ _ _ _ _ _ _ part.

 

24.  What is the output of this recursive program?

 

#include  <iostream>

void recursive( int i )

{

  using namespace std;

cout << i << " ";

if ( i < 8 )

{

i++;

recursive(i);

}

}

int main()

{

using namespace std;

recursive(3);

cout << endl;

}

 

25.  Write an iterative version of this recursive function.

 

void recursive( int i )

{

using namespace std;

if ( i < 8 )

{

cout << i << " ";

i++;

recursive(i);

}

}

 

 

26.  How many times is the following code invoked by the call recursive(4)?

a)  2

b)  4

c)  8

d)  32

e)  this is an infinite recursion.

 

void recursive( int i )

{

using namespace std;

if ( i < 8 )

{

cout << i << " ";

recursive(i);

}

}

 

27.  What is the output of the recursive function below when called with an argument of 5?

 

a)  6 7 8

b)  5 6 7

c)  8 7 6

d)  7 6 5

e)  None of these. This is an infinite recursion if the function is called with argument 5.

 

void recursive( int i )

{

using namespace std;

if ( i < 8 )

{

i++;

recursive(i);

cout << i << " ";

}

}

 

28.  True or False: Each recursion causes a new activation frame to be placed on the stack.

 

29.  True or False: Each activation frame contains all the function’s code, as well as the automatic variables and formal parameters.

 

30.  True or False: The activation frames in nested function calls are handled in a last-in/ first-out manner.

========================================================================

 

 


Solutions to Study Guide Problems

 

I. Solutions Part One

 

1.     array of characters

 

2.     This array will hold a string of 5 characters. The last position is occupied by the null character '\0', which signals the end of the string.

 

3.      

a)     The \ is an escape character that either escapes the (already) special nature of some characters, for example " to delimit a string constant, ' to delimit a character constant, or \ as an 'escape' character).  The \ may give special nature to other characters, for example, \n for new line, or \t for a tab character.

 

b)    If you try to output a \w in a string constant, for example, the  g++ compiler will warn about an unknown escape character. BC++ 4.0 does not output the backslash character, but gives no warning.

 

4.   char s[] = "Happy Face :) ";

 

5.      

a)     1 character. The \n is a single character, called newline.

b)    1 character.

c)     4, if you aren't counting the null terminator, 5 if you are.

d)    1,  if you aren't counting the null terminator, 2 if you are.

e)     5, if you aren't counting the null terminator, 6 if you are. The \ and the n are taken together to make up the newline character.

 

6.      

index:       0        1      2      3      4      5      6      7      8      9      10      11

value:       H       i               t      h      e      r       e    \0       *        *        *    <=  *  means not assigned

 

7.               char str[11];  Space for 10 characters, and a null terminator.

 

8.     These are not equivalent. The first of these places the null character '\0' in the array after the characters 'a', 'b', and 'c'. The second only assigns the successive positions 'a', 'b', and 'c' but does not put a  '\0' anywhere.

 

9.   

int index = 0;

while ( our_string[index] != \'0' )

{

our_string[index] = 'X';

index++;

}

 

10.  If the string variable does not have a null terminator, the loop can run beyond memory allocated for the string, destroying the contents.  To protect memory beyond the end of the array, change the while condition:

 

while( (our_string[index] != '\0') && ( index < SIZE) )

 

11. 

#include <string>

// this has to be in the code to get the declaration of strcpy

   using namespace std;

...

 

strcpy( a_string, "Hello" );

 

12.  The output is "The strings are NOT the same" The reason is that the strcmp function is asking whether the strings are different. (The function could be perhaps better named?) Hence, the strcmp function returns a positive or a negative number if the strings are different, and it returns 0 if the strings are the same.

 

13. 

#include <cstring>

// need to either have using directive or qualify names with std::

 

char a[9] = "Hello";  // Which array is declared 9 or 12 is

char b[12] = "Hi there";    // immaterial. There is enough room in

// each string for either string constant

if (strcmp( a, b ))

cout << "The strings are NOT the same";

else

cout << "The strings are the same";

cout << endl;

 

14.  If you use the strcpy or strcat functions from the string library without due care to the lengths of the strings, you can overwrite memory beyond that allocated for the strings, with no warning, or with a segmentation error in a memory protected environment, or perhaps hang your machine! This is an example:

 

char str[3];

strcpy( str, "Now hear this.");

cout << str << endl;

 

15.           

a)     strlen takes string argument: const source

strcat takes string arguments: target, const source

strcpy takes string arguments: target, const source

strcmp takes string arguments:  const source1, const source2

b)    strlen returns an int, the value is the number of characters up to but not including the null terminator

c)     strcmp returns an int, the value is non-0  if the strings are different, 0 if they are the same.

d)    strcpy moves characters from source, starting with the first character of source, to the first character of target, continuing character by character until the null terminator for source is transferred, without regard for the size of target.

e)     strcat moves characters from source, starting with the first character of source, to the null terminator of target, then continuing character by character until the null terminator of the source is transferred, without regard for the size of target.

f)       

16.  a) and b) are equivalent, c) and e) are equivalent.

 

17. I did it my way!

 

18.  The string "I get ... well."  is too long for the target. A chunk of memory that doesn't belong the target array will be overwritten.

 

19.  // Note: This solution was tested for strings of length 0, 1, 10,   // 100 and 1000

  // precondition: strlen has been called with a null terminated
// array of char argument

  // postcondition: the return value is the number of characters
// prior to the null character.

int strlen( const char src[] )

{

int i = 0;

while ( src[i] != 0 )

+;

// Assert: i contains the index of the null character in src.

return i;

}

 

20.Do be do,<END OF OUTPUT

 

21.  The getline function is used to input a whole line of data into a string variable.

a)     The arguments are a string variable, then an integer. The string variable receives the               input. The integer indicates the maximum number of characters to be input, plus 1 to        provide room for the null terminator. At smallest, the integer should be the declared size of        the string variable.

b)    Input stops at one less than the integer or at the carriage return, whichever occurs first.

 

22. in_stream.getline( line, 80 );

 

23. 

#include <cstdlib>

using namespace std;

 

char number1[] = "3456";

char number2[] = "3.456e-7";

int n1;

double n2;

n1 = atoi( number1 );

n2 = atof( number2 );

 

24.  The dialog proceeds as follows:

Enter a line of input:

May I get an ‘A’ in PIC10B.

May I g <END OF OUTPUT

 

25.void my_func( int a[][25], int dimension_1_size);

 

26. 

char list[10][20];

int index;

cout << "Enter 10 names, one per line:" << endl;

for (index = 0; index < 10; index++ )

cin.getline(list[index], 20);

 

27. 

for (index = 0; index <= 10; index++ )

cout << list[index][0] << endl;

 

28.   

1 2 3

1 2 3

1 2 3

1 2 3

 

29.phrase = word1 + word2;

 

30.  When the + is used with a String object as its left or right operator, the C++ compiler looks for a way to change the other object to a String object. It finds the constructor with a const char a[] argument, which it uses to accomplish this conversion.

 

31.  word is left with only "Mary" in it, complete with the null terminator. The reason is
operator >> is overloaded to skip over white space, to read only words, that is, strings of non white space characters.

 

32.   The input_line member function will read into the String object word a string of characters up to MAX_STRING_LENGTH characters or a newline, which ever occurs sooner.

 

word.input_line( cin );

 

33.   

String::String()

{

current_length = 0;

}

 

34. 

#include <cstdlib> // for exit()

 

void String::set_char( int position, char new_char )

{

    if( (position > current_length)

      || (position < 0)

      || (position >= MAX_STRING_LENGTH) )

{

  cout << "ERROR: illegal position in set_char." << endl;

  std::exit(1);

}

else

  character [position] = new_char;

if (position == current_length)

  current_length++;

}

 

35. 

cout << "Enter 20 names one per line: " << endl;

int i;

for ( i = 0; i < 20; i++)

list[i].input_line(cin);

 

36. 

cout << "Enter 20 names one per line: " << endl;

int i;

for ( i = 0; i < 20; i++)

list[i].input_line(cin);

cout << "The 20 names are: " << endl;

for ( i = 0; i < 20; i++)

cout << list[i] << endl;

 

37.  int myIntArray3D[300][100][200];  - defines a 3D array of integer type elements. By convention, myIntArray3D  is a 1D array of 300 elements, where each element is of type 1D array of size [100], and in turn each of its elements are 1D arrays of size [200] of type int.  Order of the indices fast-to-slow is 0<=x<200;  0<=y<100;  0<=z<300. The address of myIntArray3D[0][0][0]=1000,  then address of  myIntArray3D[1][25][15] = myIntArray3D[0][0][0] + [1*(100*200) + 25*(200) + 15]*sizeof(int)  =  101,060.

 

 

II. Solutions Part Two

 

1.     A pointer is the memory address of a variable. The fact that variable may occupy more than one address is accounted for by the fact that pointers have a type to which they can point. This controls what type object(s) the addresses of which a pointer may have.

 

2.  double *double_ptr;

 

3.     It looks like two objects of type int pointer, int*. Unfortunately, the * binds to the identifier, not to the int. The result it that this declaration declares int_ptr1 to be an int pointer, while int_ptr2 is an int object.

 

4.  int *int_ptr1, *int_ptr2;

or

int *int_ptr1;

int *int_ptr2;

or

typedef int* IntPtr;

IntPtr int_ptr1, int_ptr2;

 

5.     typedef int* IntPtr;

  IntPtr int_ptr1, int_ptr2;

 

6.     p1 is a pointer to int, p2 is an int.

 

7.    int v;

  int *p = &v;

 

8.      The text says "This is not crazy. This is abstraction. C++ insists that you use a pointer as an address and that you not use it as a number." In short, the C++ strong typing system requires that every object have a type, and that type is enforced. This applies to pointers as well. (You can use a cast to change a pointer to an int. C++ philosophy is to assume the programmer knows what she (or he) is doing, and to make it possible. But not inadvertently.)

 

9.      

void func( int & x ); // The answer I expect is "This declares a

// reference formal parameter." Language

// lawyers call this use of & a "reference

// declarator".

int x, y;

int *p;

 

false && true   // logical AND

p = &x;         // address of operator.

 

 

The text does NOT discuss the following possible answers. These are possible answers from a student with previous C++ experience.

 

x & y           // Bitwise AND. This is not discussed in the text.

// and I would not require this.

// previous C/C++ experience may give this answer.

 

int &r = x;     // Here the & is a reference declarator. This is

// not discussed in the text. This declares r as a

// reference to x. Use of r is equivalent to a use

// of x. A student with previous C/C++ experience

// may give this answer.

10.   

int * p;  // The answer I expect is "This declares a pointer

      // to int. The language lawyers call * as used here

      // a "pointer declarator"

* p = 17; // * is the dereference operator. This assigns 17

      // WHERE p POINTS. (I haven't said where that is.)

void func(int *p) // Declares p to be a pointer value parameter

      // Language lawyers call * here a "pointer declarator".

 

11.   

49

49

 

12.   

int *p1 = new int;

int *p2 = new int;

 

After the two declaration/initializations    

 

13.  The first assignment copies the value stored in the variable where p2 points into the variable where p2 points. The second assignment changes what p1 points at to make p1 point to the same place that p2 points.

 

14.  The new operator takes a type argument. It allocates space on the heap (or free store) of an appropriate size for a variable of the type of the argument. It returns a pointer to that memory, if there was enough space. If there was not enough space, the new operator returns the NULL pointer.

 

15.  int *p;

p = new int;

if ( NULL == p )

{

cout << "Error: Insufficient memory" << endl;

exit (1);

}

// if new succeeded in allocating memory, the program proceeds

 

16.  The delete operator deallocates the memory of a dynamic variable (one allocated on the heap) and returns this memory to the heap for reallocation.

 

17.  A dangling pointer is a pointer whose dynamic variable has been deleted. The value of that pointer that was an argument for delete is undefined, and what its value is depends on the compiler writer. Any other pointers that were previously equal to the deleted pointer are also dangling. They still point to the same memory location, but that memory location belongs to the heap (free store) manager.

 

To protect yourself against dangling pointer variables, when you delete a variable, assign it NULL Then hunt down all pointers in your code that pointed to that variable and assign them NULL.

 

18.  typedef int* IntPtr;

IntPtr my_ptr;

my_ptr = new int;

 

19.   int * value;

int size;

int i;

cin >> size;

value = new int[size];

for ( i = 0; i < size; i++ )

value[i] = i;

 

Alternately, using a typedef:

 

typedef int* IntPtr;

 

IntPtr value;

int i;

int size;

cin >> size;

value = new int[size];

for ( i = 0; i < size; i++ )

value[i] = i;

 

20.   delete [] a;

 

21.  After the call to new, the pointer a should be compared to NULL (the 0 pointer) and if the compare is true, the program should be exited. Some place, this include command is needed for the exit function.

 

#include <stdlib.h>

 

if( a == NULL)

{

cout << "Error: insufficient memory!" << endl;

exit(1);

}

 

22.  typedef char* CharArray;

 

23.  cout << "Enter 10 integers." << endl;

for ( int i = 0; i < 10; i++)

cin >> value[i];

 

24. All are correct except d). In d) a is an array name, and is not a valid l-value. An array name cannot be incremented.

 

25. 0 1 2 3 4 5 6 7 8 9

 

26.   

a)     A destructor is a member function of a class. A destructor's name always begins with a tilde, ~, followed by the class name. It isn't a destructor unless it is named in this manner.

b)    A destructor is called when a class object goes out of scope.

c)     A destructor actually does whatever the class author programs it to do.

d)    A destructor is supposed to delete dynamic variables that have been allocated by constructors for the class.  Destructors may do other cleanup tasks. 

 

27.   

a)     A copy constructor is a member function that has the same name as the class. To be a copy constructor, the formal parameters must be a reference to a class object. In fact, this is usually a const reference to a class object.

 

b)    There are three situations when a copy constructor is called:

i)      when one class object is initialized from another object of the same class

ii)     when a class object is passed by value to a function

iii)   when a class object is returned from a function.

c)     As in any constructor a copy constructor does exactly what the class author programs it to do.

d)    A copy constructor should create an exact copy of the old class object.

 

28.   In short, danger of dangling pointers and memory leaks:

Parts a) and b) The compiler will synthesize a copy constructor or do memberwise assignment.  Members will be copied, regardless of the desirability of this action. If the members are pointers, the pointers are copied. This can cause memory to be orphaned (sometimes called a memory leak). It can cause unexpected dangling pointers galore.

 

Part c) The compiler will synthesize a destructor that does nothing. You can have orphaned storage (also called memory leaks) galore.

 

29.  The first instance, the StringVar preceding the :: is the name of the class. This establishes the scope for the identifier that follows. The StringVar that follows the :: is the name of the constructor. (Remember, a constructor is a member function having the same name as the class.) The StringVar that follows const and precedes & is the type of the formal parameter, string_object.

 

30.  No. The overloaded assignment operator= must be a member of the class.

 

31.  The problem is exactly as the hint suggests, a dangling pointer. If you assign

 

my_string = my_string;

 

then you delete the value member of the my_string object. This results in my_string.value becoming a dangling pointer, that is, a pointer with its dynamic variable deleted.

 

 

 

 

III. Solutions Part Three

 

1.     Any definition that contains a reference to things of the same kind that have already been defined is recursive. A function definition that contains a call to the function being defined is said to be recursive.

 

2.     recursive

 

3.     False. A recursive function can be either a void function or a value returning function.

 

4.     The computer keeps track of recursive calls in the following way. When a function is called, the computer plugs in the arguments for the parameter(s) and begins to execute the code. If a recursive call should be encountered, then suspends the current function, saving all the information it needs to continue this incarnation of the function after the recursive call is done. When the recursive call is completed the suspended invocation continues. The only limit on the number (or depth) of recursion is limited machine resources, primarily memory. The process will not terminate unless one of the calls to the function does not depend on recursion to return a value.

 

5.     For a successful recursive solution to a problem, there must be:

 

·       One or more cases in which the function accomplishes its task by using recursive call(s) to accomplish one or more smaller versions of the task.

·       One or more cases in which the function accomplishes its task without the use of any recursive calls. These cases without any recursive calls are called base cases, non-recursive cases, or simply stopping cases.

 

6.     A stack is analogous to a stack of paper, where we assume we have an inexhaustable supply of clean sheets of paper. In order to place information on the stack, we write it on a clean piece of paper and put the paper on the stack. To get information, we can only read the top piece of paper. To get information further down, we must remove some paper. The rule is, if a piece is removed, it is thrown away.  The four word description of the stack discipline is Last-In-First-Out, or LIFO.

 

7.     Because the recursion involves overhead that iteration does not.

 

8.     The recursive version may well be clearer and easier to understand than the iterative version. This is not always the case.

9.     The answer to Question 9. is the function in Question 10.

10.   The answer to Question 10 is the function in Question 9.  

Here are both functions, with a main function (main part), and output.

// Recursive cheers function, the answer to #10.

#include <iostream>

void rec_cheers( int n )

{

using namespace std;

if ( 1 == n )

cout << "Hurray!" << endl;

else

{

cout << "Hip, ";

rec_cheers ( n - 1 );

}

}

// iterative version of cheers function, the answer to #9.

void iter_cheers( int n )

{

using namespace std;

for ( int i = 0; i < n-1; i++ ) // this is the tricky part!

{

cout << "Hip, ";

}

cout << "Hurray!" << endl;

}

 

int main()

{

rec_cheers(3);

iter_cheers(3);

}

Trial Run:

~/AW$ a.out

Hip, Hip, Hurray!

Hip, Hip, Hurray!

 

11.  // Recursive function to sum an array of int numbers.

// base case is size = 1, return a[0]

// recursive case: add the last element to the sum of the previous // elements

 

#include <iostream>

// Add array recursively

 

int sum ( const int a[], int size );

 

int main()

{

using namespace std;

int a[ 9 ] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, };

cout << sum(a, 9 ) << endl;

}

 

int sum (const int a[], int size )

{

if ( 1 == size )

return a[0];

return a[size - 1] + sum( a, size - 1 );

}

12. 

#include <iostream>

void backward( int n)

{

using namespace std;

if (n<10)

cout << n;

else

{

cout << n%10;     // write last digit

backward( n/10 ); // write the rest of the digits

}

}

 

int main()

{

using namespace std;

int n = 1234;

cout << n << endl;

backward( n );

cout << endl;

}

 

~/AW$ a.out

1234

4321

 

13. 

int g( int n)

{

if ( 0 == n || 1 == n )

return 1;

return n * g( n - 1 );

}

 

14.  This function computes (n-1)!. The error is in line //g. To get n!  out of this, line //g must be:

 

f = n * f;

 

15.   

a)     There is no infinite recursion

b)    Each stopping case returns the correct value for that case

c)     For the recursive case(s): if all recursive calls return the correct value, then the final value returned by the function is the correct value.

 

16.   

a)     There is no infinite recursion

b)    Each stopping case performs the correct action for that case.

c)     For case(s) that involve recursion, if all recursive calls perform their actions correctly, then the entire case performs correctly.

 

17.  The mid point of the mid point of the mid point... until only one element is left. mid point of lists of 32 elements, of 16 elements , of 8 elements, of 4 elements, of 2 elements, then 1 element.  6 elements at most.

 

For 1024 elements, mid points of lists of length 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1 must be examined, or at most 11 elements.

 

18.  In C++ where function name overloading is allowed, the function signature, that is, the function name and the list of argument types, determines what function we are talking about. In recursion, it is this function that is called, with the exact same signature, not some other function having the same name, but different signature as would be the case in function overloading.

 

19.  Half the subarray is eliminated in each pass of the binary search, either in the iteration of the loop or recursive call.

 

20.  The recursive binary search is sent an array and indices first and last that specify limits of a subarray. The function tests the condition, first > last to determine whether the key is not present in the array. If not, report this and quit.

 

If the key still may be present, a ‘middle’ index is computed, and the equality of this element to the key is tested. If true, report this fact and quit.

 

If neither of these occurs, then determine whether the key may be in the upper or lower half array and recursively call the function on that half the subarray.

 

21.The recursive calls are always made with a subarray starting at first to mid-1, or mid+1 to last. When you get down to one element in the array and send that to a recursive call, the next call will either find that the array element is the key, or will have first > last.

 

This example helps make this clear. Suppose key < 1, and we are searching the list 2 3 4.

We start with:

2 3   4

mid =1,  first==0,  last==2

New values:

first=1, last = mid-1 = 0   (key < 1)

first > last, key is not there, quit.

 

22.  tail

 

23.   base, non-recursive

 

24.  output: 3 4 5 6 7 8

 

 

 

25. 

void iterative( int i )

{

using namespace std;

while ( i < 8 )

{

cout << i << " ";

i++;

}

}

 

26.  e) This is an infinite recursion because no change in i is made to move closer to the non-recursive case.

 

27.  c)  Note that if this function is called with an argument of 5, the values of i that cause the recursive calls are successively 5, 6, and 7, and each gets incremented to 6, 7, 8 which are stacked in that order. The recursion unwinds. The output sees the 8 first, the 7 next, and the 6 last.

 

28.  True. Activation frame contains the automatic variables and local variables that are created for each invocation of the function.

 

29.  False. The activation records only have automatic variables and formal parameters, with a bit of other house-keeping information necessary to the restarting of the suspended calling function.

 

30.  True. This is exactly the stack discipline. It is appropriate for functions that call functions ... that call functions, then return...