CSCI 3510
Spring 2004
Practice questions for quiz 2

  1. Which of the following are part of an abstract data type specification? (Circle the letter of all that apply.)

    1. A type.
    2. Prototypes for functions in the abstract data type.
    3. A description of how the type is represented.
    4. Implementations of the functions.
    5. Conceptual meanings of the functions.

  2. Object-oriented programming in C++ can be used to make it impossible to violate the abstraction of an abstract data type.

    1. What feature of C++ makes this possible?

    2. Programmers rarely deliberately sabotage their own work. Since programmers are not supposed to violate abstractions, why is it so important that a compiler prevent them from doing so? Can't programmers police themselves?

  3. Suppose that the following structure definition is given.

       struct Widget
       {
         int side;
         char bottom[22];
         Widget(int s, char b[])
         {
           side = s;
           strcpy(bottom, b);
         }
       };
    
    1. Show how to create a new widget called frodo with side = 4 and bottom = "blue". Use the constructor.

    2. Suppose that the constructor were not provided as part of the Widget structure type. Show how to create the same widget frodo without using the constructor.

  4. When doing object-oriented programming, you typically find that functions have one less parameter than do corresponding functions that are used in procedural (non-object-oriented) computing. For example, a classical function to test whether a value x is present in a table t has two parameters, x and t, but an object-oriented function has only one parameter, x. Explain why there is one less parameter.

  5. A rational number can be represented by a pair of integers, the numerator and the denominator. For example, the rational number with numerator 1 and denominator 3 stands for 1/3. The advantage is that some numbers that can only be represented approximately using type double can be represented exactly as ratios of integers.

    An abstract data type Rational is intended to represent rational numbers. So a member of type Rational is thought of as having a numerator and a denominator. Among the operations are a constructor that takes two integers (a numerator and a denominator) and initializes a rational number; an operation flip so that x.flip() makes x into its reciprocal; an operation multiplyBy so that x.multiplyBy(y) makes x into the product of x's current value and y, where y is a rational number; an operation getNumerator that returns the numerator, and an operation getDenominator that returns the denominator. (So x.getNumerator() is the numerator of x.)

    Rational numbers are always stored in a form where the numerator and denominator have no common factors. Instead of 3/6, you store 1/2. You cannot assume that somebody who uses this data type knows this convention. There is nothing wrong with creating a rational number with numerator 3 and denominator 6. But if you then ask for the numerator, it will be 1, not 3. This can be achieved by dividing the numerator and denominator by their greatest common divisor. Assume that function gcd(m,n) is available to you. You do not need to write it.

    1. Write Rational in C++ as a class, including the constructor and methods flip, multiplyBy, getNumerator and getDenominator. Also provide a private method called reduce that reduces a rational number by dividing the numerator and denominator by their greatest common divisor. You will want to use reduce in some other functions.

    2. Write a main program that creates rational numbers 1/3 and 3/7, calculates the product of those two numbers, and prints the product in the form numerator/denominator. (So it will print "1/7".)