Midterm Examination Solutions, Spring 1999


Problem 1. In each question below declare and use pointers to change the values of variables as directed.

(a) Make x change its value from 1 to 2, then to 3, then to 4. You are allowed to mention x only once is your code.

int x = 1;

int * p = & x;
*p += 1; 
*p += 1;
*p += 1;


(b) Make r a square of size with the top left corner at (100, 100). You are allowed to mention r only once in your code.

Rect r;

Rect * q = & r;
q->left   = 100;
q->top    = 100; 
q->right  = 150;
q->bottom = 150;


Problem 2. (a) Recall that the standard struct Rect in our Mac library had just four int data members, left, top, right, bottom. Write the function OffsetRect that takes three parameters, the rectangle r to modify, and two integers, x_off and y_off, and modifies r by offsetting it by x_off, y_off. For example,

Rect r = MakeRect( 100, 100, 200, 200 );
OffsetRect( r, 50, 70 );
results is r now being the rectangle (150,170,250,270).

void OffsetRect( Rect & r, int x_off, int y_off ){
  r.left   += x_off;
  r.right  += x_off;
  r.top    += y_off;
  r.bottom += y_off;
}

(b) Assume the following declaration of the class myRect.

class myRect {
    int left;
    int top;
    int right;
    int bottom;
public:
    myRect( int l, int t, int r, int b ) : 
        left(l), top(t), right(r), bottom(b) {}
    ...
};

Write a member function Offset(..) that takes two parameters, x_off and y_off and offsets the rectangle by them. For example, the result of

myRect R( 100, 100, 200, 200 );
R.Offset( 50, 70 );
is R becoming the rectangle (150,170,250,270). Use the out-of-class definition syntax.

void myRect::Offset( int x_off, int y_off ){
  left   += x_off;
  right  += x_off;
  top    += y_off;
  bottom += y_off;
}

Problem 3. Assume the following declaration of class Counter. This class does almost nothing useful, but is very verbose about it, due to the messages its member functions print.

class Counter {
    int c;
public:
    Counter() : c(1) { cout << "***\n"; }
    Counter( int c_ ) : c(c_) { cout << "+++\n"; }
    Counter( const Counter & cnt ) : c( cnt.c ) { cout << "@@@\n"; }
    ~Counter() { cout << "###\n"; }
    void Increment(){ c++; cout << "."; }
    int GetValue()  { return c; }
    void Reset()    { c = 1; }
};
Also assume that the (equally useless) functions foo and bar are declared as follows:

void foo( Counter & cnt ){
    cnt.Reset();
    cnt.Increment();
    cnt.Increment();
}   
void bar( Counter cnt ){
    cnt.Reset();
    cnt.Increment();
    cnt.Increment();
}

Write all the output that the following program will cause to appear. You can write the corresponding output next to the line of code that produces it.

int main(){

    Counter cc[3];                        ***  default constructor 3 times
                                          ***
                                          ***
    
    Counter c1(5);                        +++  constructor Counter::Counter(int)
    
    Counter c2( c1 );                     @@@  copy constructor 

    c1.Increment();                       .
    
    cout << c1.GetValue() << endl;        6
    
    cout << c2.GetValue() << endl;        5
    
    foo( cc[1] );                         ..
    
    cout << cc[1].GetValue() << endl;     3
    
    bar( cc[2] );                         ..
     
    cout << cc[2].GetValue() << endl;     1
    
    {
        Counter c3;                       *** default constructor
        c3.Increment();                   .
        cout << c3.GetValue() << endl;    2
    }                                     ### destructor for c3  
    
    cc[0] = Counter( -2 );                +++  Counter::Counter( int ),  
                                               then Counter::operator=,
                                          ###  then destructor for the temp.
                                               instance of Counter

    cout << cc[0].GetValue() << endl;     -2

}                                         ###  destructors for 
                                          ###    cc[0],cc[1],cc[2], c1, c2
                                          ###
                                          ###
                                          ###

Problem 4. Assume the following declarations for a list of integers.

struct IntNode {
    int data;
    IntNode * next;
    IntNode( int d, IntNode * n ) : data(d), next(n) { } 
};

class IntList {
    IntNode * first;
public:
    IntList() : first( NULL ) { }
    void Add( int d ){
        first = new IntNode( d, first );
    }
    
    // prototypes required here
    int Sum();
    void AddLast( int elt );
    ...
};

(a) Write the member function Sum() that computes and returns the sum of all integers in the list. Thus the following code will print 10:

  IntList lst;
  lst.Add( 1 );
  lst.Add( 2 );
  lst.Add( 3 );
  lst.Add( 4 );
  cout << lst.Sum() << endl;   // prints 10  

int IntList::Sum(){
  IntNode * ptr = first;
  int sum = 0;
  while( ptr != 0 ){
    sum += ptr->data;
    ptr  = ptr->next;
  }
  return sum; 
}

(b, extra) Write the member function AddLast( int ) that adds a new integer at the tail of the list (notice that Add always adds at the front of the list).

void IntList::AddLast( int elt ){
  // treat empty list specially
  if( first == NULL ){
    first = new IntNode( elt, NULL );
    return;
  }
  
  // Else the list has at least one node, 
  //   i.e. first != NULL .
  // Get the pointer to the last node.
  IntNode * ptr = first;
  while( ptr->next != 0 )
    ptr  = ptr->next;
  
  // ptr now points to the last node, 
  //   i.e. ptr->next == NULL 
  ptr->next = new IntNode( elt, NULL );
}


(c, extra) Is the following (probably useless) declaration legal? Explain.

IntNode intnodearray [5];

Illegal. This declaration should create 5 new IntNodes, each by calling the default constructor. However, no default constructor is available in the description of the class, and since another constructor is defined, the default one will not be generated automatically. Compilation will fail with an error very much like IntNode::IntNode() not defined.



Sergey Bratus
5/25/1999