Solutions to Assignment 5

1. A possible program is here main file     input function.
The program is pretty long and I organized it in two files. I implemented the input part (second file) only after I carefully debugged and documented the computational part.
I left (commented) those lines of code I used in process of debugging. Some non-syntax errors I initially made and had to fix are notable:
1) Returned value 0 (instead of 1) from stub inp(), which led to the "invalid data" branch in main()
2)   for(i=i; i<N; i++)    (typo in initialization)
3) In min():   a[i]=current_min      instead of correct     current_min=a[i]
4) Made max() out of min() by Copy and Replace operations only; forgot to change the sign in comparison operation. As a result, the obtained "max()" continued to compute minimum.
I found these errors (at corresponding stages of incremental development, not all at once, of course) by examining the output of my program and comparing it with expectations.

The input function in file inpsequence.cxx is, well, long and logically complicated (many if's). It is a full-featured user-safe version. The style it is written in is terrible. A function (even a member function) shouldn't be so long. It combines several things: processing of command line arguments, validation of filenames, interactive input, and input from file. These should have been separated!

I will post a better structured program (for your information) later on, but it may use more advanced techniques such as class inheritance or a member variable that is an instances of another class.

2. Suppose that variable x of type double is defined in main(). The following line in main() is supposed to increment the value of x by 1:
       inc(&x);
The program is written in C (the compiler to be used is gcc). Which of the following implementations of function inc is correct?
  A.     void inc(double x)
     	 {
    	   x++;
    	 }
	 
  B.     void inc(double* x_ptr)
         { 
            (*x_ptr)++; 
         } 
     
  C.     void inc(double &x)
     	 {
    	    ++x;
    	 }
    
  D.     double inc(double x)
     	 {
    	   return (x+1);
    	 }
    
Answer: The correct function is B. The value x is passed from main to inc by reference. In this case, the corresponding argument of a C function must be a pointer. See Sect. 6.5. (p. 252)
What about other variants? Here is an
experimental program. Function header in variant C isn't compilable with gcc. Function headers A and D pass compilation, but they are incompatible with function call format in main().
For A, the syntax of call should have been inc(x), but it has no effect: a local copy of x in inc gets incremented, not the x in main().
For D, the call inc(x) is legal; the returned value is alltogether ignored by main() and the call has no effect. The desired effect can be achieved in case D by the call   x=inc(x).

3. Now the program is a C++ program (to be compiled with g++), in which the following line in main() is supposed to increment the value of x by 1:
       inc(x);
Which of the above implementations A-D of function inc is correct in this case and why?

Answer: The correct function is C. The syntax of function call in main() doesn't suggest whether x is passed by value or by reference. But we know that the value of x must change as a result of the call. So it must be passed by reference. The syntax as in example C is an appropriate C++ mechanism (not existing in C) in this situation. Cf. pp. 512,515,518.
(ignore the text below.) Here is an
experimental program. The header B is incompatible with call format in main().
The variants A and D don't change the value of x in main.

4. Trace execution of the following program. (Show table with line numbers and values.) Determine the output. Which member function(s) in class A could be declared private?
1    class A
2    {
3       public:
4         A();
5         ~A();
6         void init();
7         int modify(int x);
8         int getValue();
9
10       private:
11         int value;
12    };

13  #include <stdio.h>

14  int main()
15  {
16     A a;
17     int t=27;
18     printf("Main(1): a.value=%d, t=%d\n", a.getValue(), t);
19     t=a.modify(t);
20     printf("Main(2): a.value=%d, t=%d\n", a.getValue(), t);
21     return(0);
22  }
23
24  A::A()
25  {
26     printf("Constructing A\n");
27     init();
28  }
29
30  A::~A()
31  {
32     printf("Destructing A with value %d\n", value);
33  }
35
36  void A::init()
37  {
38     value=5;
39  }
40
41  int A::modify(int x)
42  {
43     x=x/2;
44     value+=x;
45     return (x-1);
46  }
47
48  int A::getValue()
49  {
50     return (value);
51  }

Solution. In the above code, I marked red the references to members of class A from outside the class. The only place where such references could occur in this program is main(). The references in lines 18,19,20 are explicit. In line 16, the default constructor is invoked, and in line 21, the destructor. So the following member functions must be declared public: constructor A(), destructor ~A(), getValue(), modify(). All remaining members can be declared private: init() and value (which is already private).

The tracing table is below. We start from the first executable line in main(). In this case, since there is a defined constructor, the declaration of a class instance is already an executable statement.
Line             What's happening                          Values of variables

 16  invoke constructor to create instance a of class A 
 24    
 26  Output: "Constructing A\n"
 27  invoke a.init()
 36
 38  ....................................................      a.value:=5
 39  return from a.init() to  a.A()
 28  return from  a.A() to  main()
 17  (in main) ..........................................      t:=27
 18a  To evaluate a number to be printed, invoke a.getValue()
 48
 50  return a.value=5 to main()
 18b The values to substitute in place of format specifiers are: 5,27
     Output: "Main(1): a.value=5, t=27\n" 
 19a To evaluate the r.h.s. of assignment, invoke a.modify(t) 
 41  (in modify) (argument received from main)                 x:=27 
 43  integer division 27/2=13                                  x:=13
 44  5+13=18                                                   a.value:=18
 45  13-1=12. Return 12 to main().
 19b (in main) Assign the received value 12 to t.              t:=12                         
 18a  To evaluate a number to be printed, invoke a.getValue()
 48
 50  return a.value=18 to main()
 18b The values to substitute in place of format specifiers are: 18,12
     Output: "Main(2): a.value=18, t=12\n" 
 21  invoke destructor a.~A()
 30  
 32  The value to substitute in place of format specifier is: 18
     Output: "Destructing A with value 18\n"    

Total output:
Constructing A
Main(1): a.value=5, t=27
Main(2): a.value=18, t=12
Destructing A with value 18
You could (can) cut and paste the program and verify that the output is exaclty this.