CPSC 225, Spring 2002
First Test, February 22

This is the first test in CPSC 225: Intermediate Programming.


Question 1: Explain the purpose of the #include directive in C++, and give an example of using it.

Answer: A #include directive simply inserts a copy of another file into your program. It is generally used to make available some declarations of functions, classes, and variables from a "library", so that you can use them in your program. For example, the directive

             #include <iostream>

makes cin and cout available, along with some related classes, constants, and variables.


Question 2: C++ makes a distinction between declarations of functions and definitions of functions. Discuss the difference. Give an example. How many declarations can a function have? How many definitions?

Answer: A declaration of a function includes all the information necessary to make it possible to call the function, including the name of the function, return type, and the number and types of any parameters. For example: "void processArray(int A[]);". A definition is a declaration that also includes the C++ code that says what the function does. Given a declaration, a compiler can compile code that uses the function, but it's not possible to link and run that code unless a definition is available. A function can only have one definition, but it can have as many declarations as you like.


Question 3: The keyword const is used in several ways in C++. Briefly describe at least two.

Answer: (1) A variable that is declared const is really a named constant whose value can never be changed. For example: "const PI=3.141592654;".
           (2) A parameter to a function can be declared const. This means that the function is not allowed to change the value of the parameter. For example, "void process(const int A[]);". Even though arrays are automatically passed by reference, the function won't be able to change the numbers in the array.
           (3) A member function in a class can be declared const by putting the word const after the function heading. For example: "int getDay() const". This makes it possible to apply the member function to a constant object.


Question 4: Suppose that A is an array of ten ints. In Java, a reference to A[17] will produce an ArrayIndexOutOfBoundsException. What would happen in C++? How does the difference reflect the differing design philosophies behind Java and C++?

Answer: In C++, this grisly error would go unnoticed and unreported by the system, unless it happens to produce a serious runtime error such as a segmentation fault. The program would be accessing memory that is not actually in the array, and therefor could be anything. C++ gains efficiency, since it takes extra time for the computer to check whether each array access is legal. The C++ designers were concerned with efficiency, and were willing to assume that programmers would take precautions not to make such errors. The Java designers put safety before efficiency.


Question 5: Write a C++ function that will return the largest item in an array of ints

Answer:

              int  max( int A[], int itemCount ) {
                    // Find the largest item among A[0], A[1], ..., A[itemCount-1].
                    // Precondition:  itemCount > 0.
                  int max;  // largest item seen
                  max = A[0];
                  for ( int item = 1;  item < itemCount;  item++ ) {
                     if ( A[item] > max )
                        max = A[item];
                  }
                  return max;
              }

Question 6: (a) Give definitions of the constructor and member functions of the following class:

           class Counter {
              public:
                 Counter;    // Constructor initializes the value to 0.
                 void up();  // Add one to the value of the counter.
                 int val();  // Return the current value of the counter.
              private:
                 int count;  // Stores the current value of the counter.
           };

(b) Explain why we can be absolutely sure that the value of a Counter object can only go up, and never down.

Answer: (a)

            Counter::Counter() {
               count = 0;
            }
            
            void Counter::up() {
               count++;
            }
            
            int Counter::val() {
               return count;
            }

(b) The value of a Counter object is stored in its count member variable. Since count is a private member variable, it can only be modified by code that is part of the Counter class. The only code in the class that changes the value is count++ in the up() member function. So, the value can only go up, not down.

(Note: In fact, the statement is not true. In C++, "private" guards against accidental access, but it's possible to get around the restriction using pointers and type-casting. A pointer in C++ can point to any address in the program's memory. Consider:

             Counter ct;
             int *p;
             p = (int*)(&ct);  // p contains the address of ct,
                               //   which is where ct.count is stored.
             (*p)--;   // The value of ct.count goes down by one.

So, "private" does not provide an absolute guarantee.)


Question 7: Write a C++ code segment that will create a file containing the line "I will learn all about C++ files" repeated 100 times. The name of the file should be "resolve.txt".

Answer:

            ofstream  out( "resolve.txt" );
            for (int i = 0; i < 100; i++)
               out << "I will learn all about C++ files\n";
            out.close(); // (not really necessary)

Question 8: Suppose that a simple class is used to represent the user names and passwords of users on a computer. The class is defined as

             class Login {
               public:
                 string username, password;
             }

Write a function that will allow a user to change his or her password. The Login object should be a parameter to the function. You can use cout and cin to prompt the user for the password and to read the new value.

Answer:

   A minimal solution:

              void changePassword( Login &login ) {
                 cout << "Enter your new password: ";
                 cin >> login.password;
              }
              
   A more realistic solution:
   
              void changePassword( Login& login ) {
                 string oldpass, newpass;
                 cout << "Changing password for " << login.username << endl;
                 cout << "Old password:  ";
                 cin >> oldpass;  // (getline(cin,oldpass) might be better)
                 if ( oldpass != login.password ) {
                     cout << "Sorry, that is not your correct password.\n";
                     return;
                 }
                 cout << "New password:  ";
                 cin >> newpass;
                 login.password = newpass;
              }

Question 9: Suppose that image is an 800-by-600 array of ints, which was declared as "int image[800][600]"/ Write a C++ code segment that will move the contents of each row in image down one row, and will move the contents of the last row into the first row. On a much smaller array, the effect would be to transform

              1   2   3   4                   9  10  11  12
              5   6   7   8        to:        1   2   3   4
              9  10  11  12                   5   6   7   8

Answer: There are many ways to do this. Here is one that uses a minimal amount of temporary storage:

              for (int col = 0; col < 600; col++) {
                 int temp = image[799][col];  // bottom item in this column
                 for (int row = 799; row > 0; row--)
                    image[row][col] = image[row-1][col];
                 image[0][col] = temp;
              }

David Eck, eck@hws.edu