CSE 109 Final Examination 8 AM Wednesday 21 December 2011 ========================SUGGESTED ANSWERS==================== 1. Consider the ADT for a calculator for miles computing per gallon. Such a calculator accumulates entries of miles and gallons and then returns the corresponding "miles per gallon." This question asks you to implement this ADT, while the next question asks you to implement a subclass of the class you implement here. In implementing the class for this question be sure it is compatible with your implementation of the sublass. Write a class Mpg for which the following code compiles and produces the indicated output. int main(){ Mpg x; x.enter(205.5,15.4).enter(94.5,4.6); cout<<"You went "<15) } =========================================================================== #include using namespace std; class Mpg{ protected: double miles,gallons; public: static const int M=0,G=1,MPG=2; Mpg(); double operator[](int index)const; friend ostream & operator<<(ostream &out,const Mpg&x); Mpg & enter(double m,double g); protected: static void check(bool b, const char *mess); }; Mpg::Mpg():miles(0),gallons(0){ } double Mpg::operator[](int index)const{ check(index>=0 && index<3,"Index must be 0, 1, or 2"); switch(index){ case M: return miles; case G: return gallons; case MPG: check( gallons>0,"Amount of gallons must be positive"); return miles/gallons; }; return 0; } Mpg& Mpg::enter(double m, double g){ check(m>0 && g>0,"Amounts of miles and gallons must be positive"); miles+=m; gallons+=g; return *this; } ostream & operator<<(ostream &out,const Mpg&x){ return out<<"Mpg("<"<20) a+=b; cout<14) cout<< MpgPlus::addFleet(c,3)<14.2857) return 0; } =========================================================================== class MpgPlus:public Mpg{ public: MpgPlus(double m, double g); const MpgPlus& operator+=(const MpgPlus&p); static MpgPlus addFleet(MpgPlus f[],int n); }; MpgPlus::MpgPlus(double m,double g){ enter(m,g); } const MpgPlus&MpgPlus::operator+=(const MpgPlus&p){ enter(p.miles,p.gallons); return *this; } MpgPlus MpgPlus::addFleet(MpgPlus f[],int n){ MpgPlus temp(0,0); while(n>0){ n--; temp+=f[n]; } return temp; } =========================================================================== 3. Assume that for each class mentioned below the declaration for the class is in a .h file of the same name, but in lower case, and the code is in a .cc of the same name, but in lower case. Class B is a subclass of class A. Class C is a subclass of class A, has the method void t(B&b), and uses a templated class that is stored in the file x.t. Class D is a subclass of class C. The main program is stored in the file prog.cc and has objects of type B and of type D. (1) For each .h file and each .cc file, write the necessary "include" statement(s). (2) Write a makefile that uses "separate compilation" for compiling prog.cc, creating the executable file "prog", and for "cleaning up." =========================================================================== a.h: #include ???? a.cc: #include "a.h" b.h: #include "a.h" b.cc: #include "b.h" c.h: #include "b.h" #include "x.t" //here is the best place, to be sure c.cc #include "c.h" d.h: #include "c.h" d.cc: #include "d.h" prog.cc: #include "d.h" prog: prog.o a.o b.o c.o d.o g++ prog.o a.o b.o c.o d.o prog.o: prog.cc a.h b.h c.h d.h x.t g++ -c -Wall -Werror prog.cc a.o: a.cc a.h g++ -c -Wall -Werror a.cc b.o: b.cc a.h b.h g++ -c -Wall -Werror b.cc c.o: c.cc a.h b.h c.h x.t g++ -c -Wall -Werror c.cc d.o: d.cc a.h b.h c.h d.h x.t g++ -c -Wall -Werror d.cc clean: rm -f *~ *.o prog =========================================================================== 4. Given the syntax diagrams below and given the C++ code below, write the functions needed for the program to compile and determine whether a string of characters given to an instance of Lex satisfies the syntax for S. Recall the Lex tokens LT, GT, LPAREN, RPAREN, IDENT, NUMBER, and EOLN. S A ---->('<')---[A]---('>')---> ---->[NUMBER]--------------------------> | ^ | +-->('(')---[A]---(')')---> | | | +--(')')--[S]--('(')<--+ +--->[IDENT]-----------> void check(bool b,const char* mess){ if(!b){ cerr<<"<---ERROR: "<"); //good string next(lex,token); //call lex.next() and display lex.str() s(lex,token); check(token==lex.EOLN," end of line expected"); cout<<"Success\n"; } =========================================================================== void next(Lex&lex,int &token){ token=lex.next(); cerr<' expected"); break; case Lex::LPAREN: next(lex,token); a(lex,token); check(token==lex.RPAREN," ')' expected"); break; default: check(token==lex.IDENT," identifier expected"); } next(lex,token); } void a(Lex &lex, int &token){ check(token=lex.NUMBER," Number expected"); next(lex,token); while(token==lex.LPAREN){ next(lex,token); s(lex,token); check(token==lex.RPAREN,"')' expected"); next(lex,token); } } =========================================================================== 5. A triple is an ordered sequence of three items. Write the template for a class Triple that implements the ADT for a triple and enables the code below to compile and produce the indicated output. Triple t(6,7,8); t[0]=14; cout< w("ONE","two","Three"); cout< class Triple{ private: X data[3]; public: Triple(const X &a=X(), const X&b=X(), const X&c=X()); X&operator[](int n); const X& operator[](int n)const; template friend ostream & operator<<(ostream &out,const Triple&t); }; template Triple::Triple(const X &a, const X&b, const X&c){ data[0]=a; data[1]=b; data[2]=c; } template X & Triple::operator[](int n){ if(n<0 || n>2){ cerr<<"Range error in operator[]"; exit(1); } return data[n]; } template const X & Triple::operator[](int n)const{ if(n<0 || n>2){ cerr<<"Range error in operator[]"; exit(1); } return data[n]; } template ostream & operator<<(ostream &out,const Triple&t){ return out<<"("<full) return rt->key[0]; tot=0; for(int j=0;j<3;j++){ if(j<2) tot+=rt->key[j]; tot+=sum(rt->child[j]); } return tot; } =========================================================================== 7. Write a C program that will compile with the gcc option -xc (e.g., gcc -xc -Wall -Werror prog.c), that reads pairs consisting of an int and a double from the text file 'q7.dat' into an array of structs, and that subsequently prints out the pairs that have been read. You can assume that the file exists and contains no more than 100 pairs. =========================================================================== #include struct A{ int k; double d; }; int main(){ FILE *f; struct A x[101]; int j,n; f=fopen("q7.dat","r"); n=0; while(fscanf(f," %d %lf",&x[n].k,&x[n].d)==2) n++; for(j=0;j