RETURN LINK: Lab 5 instructions

ENGG 335: Computing for Engineers II
Lab 5 Solutions

Author: Steve Norman
Last modified: Thu Oct 15 15:24:55 MDT 1998

Contents


Exercise A

I can't write out a complete narrative explaining out each output line can be determined by reading code, but it may help to draw some diagrams. First let me add point one and point two:
   #include <iostream.h>

   int main()
   {
     int ia[5];
     int i;
     int *pi;

     cout << "Some operations with an array of ints ...\n";
     for (i = 0; i < 4; i++) {
       ia[i] = 2 * i + 1;
       cout << "  Value of ia [" << i << "] is " << ia[i] << ".\n";
     }
     cout << '\n';

     *ia = 99;
     *(ia + 2) = 55;
     ia[1] = 11;

     pi = ia + 1;
     i = 2;

     // point one

     cout << "  Value of *(pi + " << i << ") + 1 is " << *(pi + i) + 1 << ".\n";
     cout << "  Value of *(pi - 1) + " << i << " is " << *(pi - 1) + i << ".\n";
     cout << "  Value of *(&ia[1] + " << i << ") is " << *(&ia[1] + i) << ".\n";
     cout << "  Value of pi - ia is " << pi - ia << ".\n";

     pi--;
     i++;

     // point two

     cout << "  Value of *pi is " << *pi << ".\n";
     cout << "  Value of pi - &ia[2] is " << pi - &ia[2] << ".\n";

     cout << "\nSome operations with a string ...\n";
     const char *pc = "abcdefgh";
     cout << "  " << pc << '\n';
     cout << "  " << pc + 3 << '\n';
     cout << "  " << pc + 6 << '\n';

     return 0;
   }
Here are the diagrams:

Diagrams for Exercise A

[back to top of document]


Exercise B

Here are the corrected definition for my_strcpy and a simple, correct definitions for my_strcat:
// There was a DEFECT in the following definition.  It has been fixed.
char *my_strcpy(char *dest, const char *source)
{
  char *result = dest;
  while (*source != '\0') {
    *dest = *source;
    dest++;
    source++;
  }
  *dest = '\0';  // The addition of this line fixes the defect.

  return result;
}

char *my_strcat(char *dest, const char *source)
{
  char *result = dest;

  // Find where to start putting new chars in dest string.
  while (*dest != '\0')
    dest++;

  // Copy chars.
  while (*source != '\0') {
    *dest = *source;
    dest++;
    source++;
  }
  *dest = '\0';

  return result;
}

[back to top of document]


Exercise C

Note that we haven't given any standard graphical notation for showing a pointer pointing past the end of an array. So any clear indication of this state would be acceptable. The diagram below shows how I chose to represent p and past_end.

point one in Exercise C

[back to top of document]


Exercise D

This was a very simple exercise, but since I said I would publish a solution, here it is.

Revised class definition (in Counter.h)

class Counter {
public:
  Counter();
  int count() const;
  void increment();
  void decrement();  // This line is the only change.
private:
  int countM;
};

New function definition (in Counter.cpp)

void Counter::decrement()
{
  countM--;
}

Revised definition of main (in exAprog.cpp)

int main()
{
  Counter c;
  cout << "initial value of c.count() is " << c.count() << endl;

  c.increment();
  c.increment();
  cout << "after 2 increment calls, c.count() is " << c.count() << endl;

  // The next three lines are new code to demonstrate the decrement
  // function.
  c.decrement();
  c.decrement();
  cout << "after 2 decrement calls, c.count() is " << c.count() << endl;

  return 0;
}

[back to top of document]


Exercise E

New function definition (in AList.cpp)
void AList::remove(int pos)
{
  assert(pos >= 0 && pos < length());

  lengthM--;
  for (int i = pos; i < lengthM; i++)
    itemM[i] = itemM[i + 1];
}

Program output including tests of remove operation

expected contents: [empty list]
actual contents  : [empty list]

expected contents: 11 22 33 44 55
actual contents  : 11 22 33 44 55

expected contents: 500 400 300 200 100
actual contents  : 500 400 300 200 100

expected contents: 101 501 401 301 201
actual contents  : 101 501 401 301 201

expected contents: 501 401 301 201
actual contents  : 501 401 301 201

expected contents: 501 401 301
actual contents  : 501 401 301

expected contents: 501 301
actual contents  : 501 301

No assertions failed.
If actual contents always matched expected contents, all tests were passed.

[back to top of document]


Exercise F

Here are links to the files for a solution:

Note: The instructions aren't clear about what the remove operation should do. It's reasonable to decide that the argument to remove should be an item instead of an index:

   void remove(ListItem item);
   // PROMISES:
   //   If the list contains one or more copies of item, exactly one
   //   copy of item is removed, and items at the tail of the list
   //   are shifted to fill the gap.
Of course, if you make this choice, the implementation and test code will have to change as well.

[back to top of document]


Exercise G

Point One:
Exercise G: diagram for Point One

Point Two:
Exercise G: diagram for Point Two

Point Three:
Exercise G: diagram for Point Three

[back to top of document]


Exercise H

New function definitions (in Cplx.cpp)
void cplx_subtract(Cplx z1, Cplx z2,  Cplx *presult)
{
  presult->real = z1.real - z2.real;
  presult->imag = z1.imag - z2.imag;
}

Cplx cplx_multiply(const Cplx *pz1, const Cplx *pz2)
{
  Cplx result;
  result.real = pz1->real * pz2->real - pz1->imag * pz2->imag;
  result.imag = pz1->real * pz2->imag + pz1->imag * pz2->real;
  return result;
}

void cplx_divide(const Cplx *pz1, const Cplx *pz2, Cplx *presult)
{
  assert(pz2->real != 0 || pz2->imag != 0);

  double a = pz1->real, b = pz1->imag;
  double c = pz2->real, d = pz2->imag;
  double c2_plus_d2 = c * c + d * d;
  presult->real = (a * c + b * d) / c2_plus_d2;
  presult->imag = (b * c - a * d) / c2_plus_d2;
}
(Note the use of local variables in cplx_divide--doing this makes it much easier to check the code against the formula in the instructions.)

Revised definition of main (in useCplx.cpp)

int main(void)
{
  Cplx w, z;                    /* entered by user */
  Cplx sum;                     /* sum of w and z */
  Cplx diff;                    // w - z
  Cplx product;                 // w * z
  Cplx quotient;                // w / z

  cout << "This programs needs values for complex numbers w and z.\n";

  cout << "  Please enter the real part of w     : ";
  cin >> w.real;
  cout << "  Please enter the imaginary part of w: ";
  cin >> w.imag;

  cout << "  Please enter the real part of z     : ";
  cin >> z.real;
  cout << "  Please enter the imaginary part of z: ";
  cin >> z.imag;

  cout << "\nw is (" << w.real << ") + j(" << w.imag << ").\n";
  cout << "z is (" << z.real << ") + j(" << z.imag << ").\n";

  sum = cplx_add(w, z);
  cout << "\nsum is (" << sum.real << ") + j(" << sum.imag << ").\n";

  cplx_subtract(w, z, &diff);
  cout << "\nw - z is (" << diff.real << ") + j(" << diff.imag << ").\n";

  product = cplx_multiply(&w, &z);
  cout << "\nw * z is (" << product.real
       << ") + j(" << product.imag << ").\n";

  cplx_divide(&w, &z, &quotient);
  cout << "\nw / z is (" << quotient.real
       << ") + j(" << quotient.imag << ").\n";

  return 0;
}

[back to top of document]