COSC 1320 - C++ Programming and
ITSE 1307 - Introduction to C++ Programming
Bob Comer, Professor of Computer Studies


Exam 3 Review
Answers to General Questions

Please let me know if you find any errors in the answers.

Note: All chapter numbers refer to the Gaddis textbook.

Chapter 10 Pointers

1. I expect you to be able to manipulate the value of a variable of a simple type using a pointer. This is not particularly useful, it just demonstrates that you know how pointers work. For example, given integer variable num, write code to declare a pointer variable called numPtr and store the address of num in numPtr. Then write code to change the value of num to 5 and print it's value without using the variable name (use the pointer).

int num = 10;   // given

int *numPtr;
numPtr = #
*numPtr = 5;
cout << *numPtr << endl;   // prints 5 (the value of num)
cout << num << endl;       // prints 5 (the value of num)


2. The following function (shown with sample call) uses reference parameters to exchange the values of the arguments in the call. Re-write the function to use pointers instead of reference parameters (re-write the sample call also). Note: when you want to change the values of the arguments in a function call, you really should use reference parameters, not pointers. This is just an exercise to show how pointers work.

Call:

int x = 10, y = 20;

swap( x, y );

function definition:

void swap( int& num1, int& num2 )
{
   int temp;
   temp = num1;
   num1 = num2;
   num2 = temp;
};

The revised code using pointers is:

Call:

int x = 10, y = 20;

swap( &x, &y );

function definition:

void swap( int *num1, int *num2 )
{
   int temp;
   temp = *num1;
   *num1 = *num2;
   *num2 = temp;
};

3. I expect you to be able to dynamically allocate memory for a value of a simple data type. For example, write code to dynamically allocate memory for a float value, store 6.5 in it, and then print it's value.

float *fPtr;
fPtr = new float;
*fPtr = 6.5;
cout << *fPtr;
delete fPtr;


4. I expect you to be able to dynamically allocate an array of a simple data type. For example, write code to dynamically allocate an array of 5 integers, initialize the array to { 10, 20, 30, 40, 50 }, and then print the values in the array.

Note that you can use either array or pointer notation to access the dynamically allocated array (I use array notation).

int *intArray;
intArray = new int[5];
int index;

for ( index = 0; index < 5; index++ )
{
   intArray[index] = ( index + 1 ) * 10;
   cout << intArray[index];
}
delete [] intArray;


5. I expect you to know the relationship between pointers and arrays in C++.(see section 10.3). Here are some notes that I wrote on the topic.

This is not a question - just some notes.

Questions 6 - 10 refer to this struct declaration:

struct Item
{
   int itemNo;
   char desc[41];
   float price;
};


6. Write the declaration for a variable called itemPtr that can hold the address of an Item struct. Then dynamically allocate an Item struct and set it's item number to 10, it's description to "Granny Smith Apples", and it's price to 1.89.

Item *itemPtr;

itemPtr = new Item;
itemPtr->itemNo = 10;
strcpy( itemPtr->desc, "Granny Smith Apples" );
itemPtr->price = 1.89;


7. Write a function that takes as parameters a pointer to an Item struct, an item number, a description, and a price. Your function should assign the item number, description, and price to the struct data members.

void store( Item *itemPtr, int anItem, char aDesc[], float aPrice )
{
   itemPtr->itemNo = anItem;
   strcpy( itemPtr->desc, aDesc );
   itemPtr->price = aPrice;
}

8. Write a declaration for an array of 150 pointers to structs of type Item called itemPtrs. Then write code to dynamically allocate an Item struct, store it's address in the first element of itemPtrs, then set it's item number to 10, it's description to "Granny Smith Apples", and it's price to 1.89.

Item *itemPtrs[150];

itemPtrs[0] = new Item;
itemPtrs[0]->itemNo = 10;
strcpy( itemPtrs[0]->desc, "Granny Smith Apples" );
itemPtrs[0]->price = 1.89;


9. Write a function that prints the descriptions of all the elements in array itemPtrs where the price is 2.0 or over. You can assume that the array is full (each element of the array points to an Item object).

void print( Item *itemPtrs[] )
{
   int index;
   cout << "List of items with price >= 2.00" << endl;
   for ( index = 0; index < 150; index++ )
      if ( itemPtrs[index]->price >= 2.0 )
         cout << itemPtrs[index]->desc << endl;
}

10. Write a function that returns a count of the number of Items in array itemPtr whose price is 2.0 or greater. You can assume that each element of the array points to an Item object.

int countNotCheap( Item *itemPtrs[] )
{
   int index;
   int count = 0;
   for ( index = 0; index < 150; index++ )
      if ( itemPtrs[index]->price >= 2.0 )
         count++;
   return count;
}

11. Write a declaration for a structure to hold a date as 3 integer values: the month, day, and year. Then write code to dynamically allocate a date, store some information in it, and print it out.

struct Date
{
   int month;
   int day;
   int year;
};

Date *hired;
hired = new Date;
hired->month = 12;
hired->day = 1;
hired->year = 1999;
cout << "Hire date: "
     << hired->month << '/'
     << hired->day << '/'
     << hired->year % 100 << endl;

A2. Reviw the following Example C++ Program that dynamically allocates structs and stores their addresses in an array of pointers:

itemptr.cpp

The following questions (12 - 17) refer to this class declaration:

class Item
{
private:
   int itemNo;         // inventory item number
   char desc[61];      // item description
   float price;        // item price
public:
   Item();
   Item(int, char [], float);
   void set(int, char [], float);
   int getItemNo();
   const char *getDesc();
   float getPrice();
};

Item::Item()
{
   itemNo = 0;
   strcpy( desc, "");
   price = 0;
}

Item::Item(int item, char itemDesc[], float itemPrice)
{
   set(item, itemDesc, itemPrice);
}

void Item::set(int item, char itemDesc[], float itemPrice)
{
   itemNo = item;
   strcpy( desc, itemDesc );
   price = itemPrice;
}

int Item::getItemNo()
{
   return itemNo;
}

const char * Item::getDesc()
{
   return desc;
}

float Item::getPrice()
{
   return price;
}

12. Class objects can be dynamically allocated similar to the way structs are dynamically allocated. Given the Item class declared above, write client code to create a variable to hold the address of an Item object. Then dynamically allocate an Item object and set it's item number to 10, it's description to "Granny Smith Apples", and it's price to 1.89.

Item *itemPtr;

itemPtr = new Item;
itemPtr->set( 10, "Granny Smith Apples", 1.89 );


13. Write client code to declare an array called itemPtrs of 150 pointers to Item objects.

Item *itemPtrs[150];

14. Write client code to dynamically allocate an Item object, store it's address in the first position of array itemPtrs, and set it's item number to 10, it's description to "Granny Smith Apples", and it's price to 1.89.

itemPtrs[0] = new Item;
itemPtrs[0]->set( 10, "Granny Smith Apples", 1.89 );

15. Write a function that prints the descriptions of all the elements in array itemPtrs where the price is 2.0 or over. You can assume that the array is full (each element of the array points to an Item object).

void print( Item *itemPtrs[] )
{
   int index;
   cout << " List of items with price >= 2.00" << endl;
   for ( index = 0; index < 150; index++ )
      if ( itemPtrs[index]->getPrice() >= 2.0 )
         cout << itemPtrs[index]->getDesc() << endl;
}

16. Write a function that returns a count of the number of Items in array itemPtr whose price is 2.0 or greater. You can assume that each element of the array points to an Item object.

int countNotCheap( Item *itemPtrs[] )
{
   int index;
   int count = 0;
   for ( index = 0; index < 150; index++ )
      if ( itemPtrs[index]->getPrice() >= 2.0 )
         count++;
   return count;
}

17. Given that the Item class contains a second constructor that allows the client programmer to declare an Item object and specify it's initial values in a single statement, write a statement that dynamically allocates an Item object and initializes it's item number to 10, it's description to "Granny Smith Apples", and it's price to 1.89.

Item *itemPtr = new Item( 10, "Granny Smith Apples", 1.89 );

A1. Review the following Example C++ Program that dynamically allocates class objects and stores their addresses in an array of pointers:

itemptr2.cpp

Chapter 11 More About Classes

1. Given the partial class definition:

class Point
{
private:
   int x;
   int y;
public:
   ...
};

You want to add a constructor function that sets each of the data members to zero. What is wrong with this constructor implementation?

Point::Point( int x, int y )
{
   x = 0;
   y = 0;
}

The object that is being initialized by the constructor is passed implicitly to the constructor function. (Actually, a pointer to the object called this is passed.) The parameters to the function are just 2 integers, NOT the member variables of the object. This function just initializes its parameters to zero, and makes no changes to the object at all. In fact, since the parameters have the same names as the object member variables, you cannot access the member variables of the object without using the this pointer. The correct version of this function is:

Point::Point( )
{
   x = 0;
   y = 0;
}

2. Given the partial Point class from the previous problem, you want to add a set function that changes the data members to values specified by the client programmer. What is wrong with this implementation?

void Point::set( int newX, int newY ) const
{
   x = newX;
   y = newY;
}

The const keyword makes this a constant member function. That means that the compiler will not allow the data members of the object that invokes this function to be changed. We need to remove the const keyword to allow new values to be stored in the data members:

void Point::set( int newX, int newY )
{
   x = newX;
   y = newY;
}

Chapter 12 More about Characters, Strings, and the string Class

1. Write the declaration for a C-string (character array) called paperColor (it should be able to hold a 40 character color name plus the null terminator character). Then write code to input a value for paperColor from the keyboard. (You can assume that the input will not contain any blanks.)

char paperColor[41];
cout << "Enter the paper color: ";
cin >> paperColor;

2. Using your variable from question 3, write code to set variable paperPrice to 3.95 if paperColor is "blue".

if ( strcmp( paperColor, "blue" ) == 0 )
   paperPrice = 3.95;

3. Using your variable from question 3, write code to store "beige" in paperColor. Then write code to print the value of the variable (include a descriptive label).

strcpy( paperColor, "beige" );
cout << "The paper color is " << paperColor << endl;

4. Write the declaration for a C-string (character array) called sentence (it should be able to hold 80 characters plus the null terminator character). Then write code to input a value for sentence from the keyboard. (Assume that the input is on a line by itself and that it may contain blanks.)

char sentence[81];
cout << "Enter a sentence: " << endl;
cin.getline( sentence, 81 );

5. To copy one string into another, you should use the strcpy() function (the assignment operator will not work). To help you understand how C strings work, try to write your own version of the strcpy() function. Make it a void function. Your function prototype should look like this:

void strcpy( char toString[], char fromString[] );

void strcpy( char toString[], char fromString[] )
{
   int index = 0;

// copy all characters from fromString to toString
   while ( fromString[index] != '\0' )
   {
      toString[index] = fromString[index];
      index++;
   }
// now put the null terminator character in toString
   toString[index] = '\0';
}

6. Given the code segment:

char string1[31], string2[31]; 
cout << "Type a sentence and press enter: " << endl;
cin >> string1;
cin.getline(string2, 31);
cout << string1 << endl;
cout << string2 << endl;

What is printed if the input is "It sure is hot today."?

When the extractor operator is used to input a string, it will do the following:

  1. Read and discard any leading whitespace characters (blanks, tabs, and newlines).
  2. Read characters and insert them into the string until a white space character is encountered (the whitespace character will not be input).
  3. Add the null terminator character into the string.

When the member function getline is used to input a string, it will:

  1. Read characters and insert them into the string until it has read one less than its second argument, or up to the first newline character, whichever comes first.
  2. Insert the null terminator character at the end of the string.
  3. If the next character in the input stream is a newline, getline will read and discard it.

The output is:

It 
 sure is hot today.


7. Write the declaration for a string object called paperColor. Then write code to input a value for paperColor from the keyboard. (You can assume that the input will not contain any blanks.)

string paperColor;
cout << "Enter the paper color: ";
cin >> paperColor;

8. Using your variable from question 7, write code to set variable paperPrice to 3.95 if paperColor is "blue".

if ( paperColor == "blue" )
   paperPrice = 3.95;

9. Using your variable from question 7, write code to store "beige" in paperColor. Then write code to print the value of the variable (include a descriptive label).

paperColor = "beige";
cout << "The paper color is " << paperColor << endl;

10. Write the declaration for a string object called sentence. Then write code to input a value for sentence from the keyboard. (Assume that the input is on a line by itself and that it may contain blanks.)

string sentence;
cout << "Enter a sentence: " << endl;
getline( cin, paperColor );

11. Given the code segment:

string string1, string2; 
cout << "Type a sentence and press enter: " << endl;
cin >> string1;
getline(cin, string2);
cout << string1 << endl;
cout << string2 << endl;

What is printed if the input is "It sure is hot today."?

The output is:

It 
 sure is hot today.


Chapter 13 File I/O

1. Write code to input 10 names (which may contain spaces) from the keyboard and output the names to a file. Include the declaration for your file object and code to open the file. The file should be named "friends.txt".

ofstream outf;
string name;
int i;

outf.open( "friends.txt" );
cout << "This program will save the names"
     << " of 10 friends in file \"friends.txt\"." << endl;
for ( i = 0; i < 10; i++ )
{
   cout << "Enter name: ";
   getline( cin, name);
   outf << name << endl;
}
outf.close( );

2.A file contains one line of information about each home that was sold in Austin last year. You do not care about the information in the file, but you do need to know how many homes were sold in Austin last year. Write C++ code to do the job. Include the declaration for your file object and code to open the file. The file is named "HomeSales.txt", and each line in the file is 65 characters or less.

ifstream inf;
string buffer;
int homeCnt = 0;

inf.open( "HomeSales.txt" );
if ( !inf )
{
   cout << "Could not open file HomeSales.txt" << endl;
   exit( 1 );
}
getline( inf, buffer );
while ( !inf.eof( ) )
{
   homeCnt++;
   getline( inf, buffer );
}
cout << "Number of homes sold is "" << homeCnt << endl;
outf.close( );

Chapter 17 Linked Lists

1. Under what circumstances might it be better to use a linked list instead of an array of structs or objects? Under what circumstances might it be better to use an array of structs or objects instead of a linked list? Issues: max size, shrink/grow, editing (insert/delete), direct access versus traversal.

Size of the problem (amount of information required)

If you have a pretty good idea of the amount of data a program needs to handle, an array might be the best choice. Just be sure to declare the array to hold the maximum amount of information that the program might need to process. For example, if most users of an inventory control program will have 100 to 150 inventory items, and no users will have more than 200 items, you might declare an array of 200 inventory items.

On the negative side, the size of an array must be a constant. So the size of an array is fixed at compile-time. When you store data in an array, you set an upper limit on the number of data items that can be processed. The only limit on the size of a linked list is the size of the computer's memory. In situations where the number of data items that will need to be processed is unknown, a linked list may be a better choice.

As another example, suppose that some users of an inventory control program will have up to 200 inventory items. But other users may only have 50 inventory items. Allocating an array of 200 inventory items when you only need to store 50 wastes memory. In situations where the amount of data that different users will need to process varies a lot, a linked list might be a good choice. (Note: it is usually not practical to create a custom version of a program for each user. For example, would a company want to sell one version of a word processor to users who only need to create small documents and a different version to users who need to create larger documents?)

Editing sorted lists of data

Say you are keeping a list of inventory items where each item is represented as a structure or object. The list of items may change - items may be added to the list or removed from the list. You might want to keep the list in some pre-determined order - maybe sorted on the inventory item number.

If you store the list in an array of structs or array of objects, inserting or deleting inventory items can involve a substantial amount of work. For example, if you need to insert a new inventory item at index 95 of the array, all items from index 95 through the end of the list need to be copied to the next higher position in the array to make room for the new item. If you need to delete the item at index 80 in the array, you need to fill in the hole left by the deleted item by copying the item from index 81 into the vacant position, and each remaining item in the list must be copied to the next lower index in the array.

If the list is stored in a linked list, a new inventory item can be added by allocating a new struct or object for the new item, then changing links (pointers) in the list to add the item. Deleting an item in the list merely involves changing the links to bypass the deleted item and then freeing the deleted struct or object. With linked lists, you never have to move the data from one place to another when inserting or deleting. So linked lists can be much more efficient in this situation.


Return to C++ Home Page

Copyright: Ó 2005 by the Austin Community College.
Department of Computer Studies. All rights reserved.
Comments to:
Bob Comer
Last updated: December 12, 20009