This is an important discussion of Quiz #2 for COM1101, Winter 2001, Prof. Futrelle's section. Why? Because this material will *also* be on the Midterm, so this is your chance to really learn it and do well on the Midterm. There will be additional material on the Midterm that will be posted for you and gone over in the review in Monday's class, 2/12/2001. COME TO THE CLASS FOR THE REVIEW BECAUSE IT WILL NOT EMPHASIZE THE MATERIAL HERE BUT WILL EMPHASIZE OTHER MATERIAL YOU'LL NEED TO KNOW FOR THE MIDTERM. AND READ THE REVIEW NOTES I'LL BE POSTING. I CANNOT EMPHASIZE TOO STRONGLY THAT THE PROPER WAY TO PREPARE TO WRITE THE ANSWERS TO QUESTIONS ON A TEST IS TO PRACTICE WRITING OUT CODE ON YOUR OWN AND CHECKING IT WITH THE BOOK OR BY TRYING TO COMPILE AND RUN WHAT YOU WRITE. This message may wrap lines in your mail program, but you can probably see it better in your browser, where it's at: http://www.ccs.neu.edu/home/futrelle/teaching/com1101w2001/tests/index.html In the discussions below, I have not distinguished my comments from the questions themselves, but when you get your quizzes back in the morning, you can see which are which. Here is the grade distribution for Quiz 2: 100 100 100 100 100 98 96 96 96 94 93 92 90 90 88 88 87 87 87 84 84 83 83 80 77 76 76 75 75 74 74 72 72 71 71 71 70 68 68 68 68 67 67 65 65 63 62 62 62 59 59 58 55 54 53 51 50 50 45 36 34 34 34 20 Median is 72 and the mean is 73.4. -- RPF COM 1101 Foundations of Computer Science Winter 2001 -- Professor Futrelle College of Computer Science, Northeastern U., Boston, MA Discussion of results of Quiz 2 -- given Wednesday, February 7th (This was the red quiz.) Question 1: Below is a set of items of code, "scrambled" -- not in their original order. You are to assign each item to one of three file types: The Interface File, the Implementation File or the Application File. Make three lists of items, one for each file type. List the numbers (only the numbers!) in the order that they should appear in each file (when the order is important) e.g., something that looks like this but with the numbers in the right places. Interface File -- has prototypes and Class ADTs w. prototypes 2 and 4 Implementation File -- has definitions 3 and 5 Application File -- has the "application", the main() program that runs 1 Here are the code items: 1. int andMoreFun(){ return 7;} 2. int andMoreFun(); 3. void main(){fun(); cout << andMoreFun() << " times more fun!";} 4. void fun(); 5. void fun(){cout << "A bit of fun or " << endl;} Many got the pairings right but the names of the files mixed up. I was not harsh in grading if you got them grouped correctly, since this was partly a terminology issue. When the above code is properly organized, compiled and run, what does it print out? A bit more fun or 7 times more fun! Note that there's an endl after "or" -- many forgot this. Question 2: 1. Write the prototype for a void function myTruck() of one argument where the argument is an array of objects of class Truck. (You needn't define the class and note that myTruck() is not a member function of the class.) 2. Write the definition of myTruck() such that it prints the year field of the truck at array element 9. 3. Write an example of a call to the function myTruck(), passing it an array of Truck objects, held in the variable: Truck myTruckArray[30]. 2.1 A prototype must have no body and the return type and the types of each argument must be specified. So the prototype of myTruck() must be, void myTruck(Truck []); or it can be void myTruck(Truck tr[]); It is not correct to omit the argument type. Some put int as the type, but the type specified was Truck. Some put in the size of the array, 30. That's wrong, since such functions take arrays of any length. A few involved the prototype in a class definition, but it was stated that myTruck() was not a member function. 2.2 The definition must have the same return type and the same argument types as the prototype. First, it says that the function prints something, so it must have a cout << .... in it. Second it says what it is to print. For the 9th element of the array it is to print the year field. Now the 9th element of an array of Trucks is a Truck object (not a class, but an object, a particular instance, with its own value of year). So here's a correct definition: void myTruck(Truck tr[]) { cout << tr[9].year ; ] That is, tr[9] is a Truck object and you access the field of any object with the dot operator (unless it is a pointer to an object -- not considered in this quiz). It is never correct to include a class name before a dot operator. Only a class instance or object. For example, if we had a collection of Car objects each with different speeds, it would make no sense to write Car.speed -- which car would that be for? 2.3 As I and the book have emphasized, passing an entire array to a function is a simple process. The call is simply written as, myTruck(myTruckArray); Note that no [] is used and the dimensions are certainly not used. All the function is getting is the location of the beginning of the array. Trying to pass the function an argument such as myTruckArray[30] would have two problems: It wouldn't compile because the argument type would be wrong. There could be functions that take a single Truck object as an argument, but even then, myTruckArray[30] would not be a proper Truck object, since the array indeces only go from 0 through 29. Question 3: Here is the API specification for a Rectangle class: // sets the dimensions of the rectangle void setDimensions(double length, double width); // returns the length of the rectangle double getLength(); Write an ADT for the class that has only the private member variables width and area, both of type double, as well as the two public member functions. Write definitions for the member functions setDimensions() and getLength() where the former behaves as if it is setting the dimensions, as evidence by the latter function that returns the value of the length. That is, the class behaves externally as if it contains the length and width, but only stores the area and width. Note that the member variables are not in the API, since they're not accessible, they're private. But writing out the ADT for the class means giving the class definition but without the definitions for the member functions, only their protoypes. So here's the ADT for the Rectangle class. Happily, most students got this right. That's very good. class Rectangle { public: // copied from above void setDimensions(double length, double width); double getLength(); private: double width, area; }; // most got this semicolon right The problems began with the definitions of the functions. In *abstract data type*, the internal representation does not have to be the same as what's accessible outside the class. In this case each object of type Rectangle can only store the value of the width and area. But of course the length can be returned simply by returning the quotient area/width, since area = length*width, as practically everyone (but not everyone!) realized. PROBABLY THE BIGGEST DIFFICULTY THAT EVERYONE HAD WITH THIS PROBLEM IS THAT MANY SEEMED TO THINK THAT VALUES ARE ALWAYS GOTTEN FROM THE USER. THAT'S RARELY THE CASE IN REAL SYSTEMS! IF YOU RUN THE DATE FUNCTION IN UNIX, IT USES AS ITS ARGUMENT THE TIME IT GETS FROM THE SYSTEM AND THEN FORMATS IT AS A DATE AND TIME AND PRINTS IT OUT. IT WOULD BE ABSURD FOR IT TO ASK YOU FOR THE TIME; YOU'RE ASKING IT! SIMILARLY IF A WEB SERVER IS RUNNING A PROGRAM TO TELL YOU IF SOMETHING IS IN STOCK AT A STORE, IT DOESN'T GET ITS INPUT FROM YOU OR EVEN FROM AN EMPLOYEE, IT GETS IT FROM A DATABASE THAT RECORDS WHAT'S IN STOCK. STUDENTS ARE SO USED TO INTERACTING WITH SYSTEMS THAT THEY DON'T REALIZE THAT 99% OF WHAT GOES ON INSIDE SYSTEMS IS THAT THE VARIOUS FUNCTIONS INSIDE THE SYSTEM CALL ONE ANOTHER GIVING THE FUNCTIONS VALUES THEY GENERATE, NOT GET FROM YOU THE USER. AS ANOTHER EXAMPLE, IN MY CAR SIMULATION PROGRAM THERE IS NOT ONE SINGLE cin >> STATEMENT. I SIMPLY PUT THE VALUES I WANT TO USE AS VALUES OF VARIABLES IN THE PROGRAM BEFORE I COMPILE IT AND THEN IT USES THOSE VALUES IN CALLS TO FUNCTIONS AND THOSE FUNCTIONS MAY CALL STILL OTHERS. AT NO TIME DOES IT GET INPUT FROM ME, ONCE THE PROGRAM RUNS. THE FUNCTION IN MY PROGRAM ACCEPT AND RETURN VARIOUS VALUES WHILE IT RUNS, BUT IT NEVER REQUESTS ANY INPUT FROM ME AND THE ONLY OUTPUT IT EVER PRODUCES ARE SOME POSITIONALLY LAID OUT CHARACTERS. So below are proper definitions of the functions, and none of them do, or should(!), get any input from the user: The setDimensions() function is to set the values inside any Rectangle object (instance) given the values passed to it as arguments. Since only the length and width are passed to the function and only the width and area are stored internally, a tiny bit of computation is required. Furthermore, the name of the arguments should NOT be the same as the names of the member variables. That produces name clashes. The majority of you just used the same names. If you tried this, the member variable would never get set, only the local variable named as the argument. Defintion: void Rectangle::setDimensions(double lengthArg, double widthArg){ width = widthArg; area = width * lengthArg; // so now the object has all it needs } Some people had the function above return a value. A void function cannot have a return statement. Here's a use of the function above: Rectangle r; r.setDimensions(standardLength*2.0, standardWidth - 4.0); Many people tried to introduce a length variable in the function setDimensions, but of course there's no length member variable in the class Rectangle, so this would accomplish nothing. But in the function getLength(), the result is to be returned to whatever program calls the function. Definition: double Rectangle::getLength(){ return area/width; // no need to define a local variable length } Here's a typical use of the function above: Rectangle rr; initialize(rr); if(rr.getLength()) > maxLength) { rr.storeInFile(rectFile); } Note that nothing is asked of the user and nothing is printed. In the example above, the returned value is compared to maxLength and then discarded. RETURNING A VALUE DOES NOT MEAN PRINTING IT! When the sqrt() function returns a value, e.g., a = sqrt(25), it does not print anything. There is no print statement *inside* the sqrt() function and you should not generally put any print statement inside a function that returns a value. You simply use return and let the program that uses the value returned decide what to do with it. Whether you choose to print the value the sqrt returns or not depends on what you are using it for. BOTTOM LINE: SETTING A VALUE ALMOST NEVER MEANS ASKING THE USER FOR A VALUE AND RETURNING A VALUE ALMOST NEVER MEANS PRINTING IT. IF YOU EVER THINK YOU NEED TO DO THIS, THINK AGAIN! THERE ARE COMPUTER SCIENCE TEACHERS WHO INSIST THAT THEIR STUDENTS WRITE SOME PROGRAMS WITHOUT ANY USER INPUT OR OUTPUT AT ALL. A HUGE SIMULATION PROGRAM FOR SIMULATING A NEW AIRPLANE DESIGN MAY RUN FOR 30 HOURS ON A SUPERCOMPUTER AND PASS ARGUMENT VALUES AND RECEIVE BACK RETURN VALUES FROM MANY BILLIONS OF COMPUTATIONS, ONLY GIVING A TINY FRACTION OF ITS VALUES AS OUTPUT FOR USERS TO LOOK AT. IF EVERY FUNCTION IN THE SIMULATION THAT RETURNED A VALUE PRINTED, IT COULD EASILY USE UP THE WORLD'S SUPPLY OF PAPER IN A FEW DAYS OR WOULD WRITE BILLIONS OF LINES OF OUTPUT TO A SCREEN. WHO COULD READ THAT?!