CSE 109 Final Examination Thursday 15 December 2005 <<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>> 1. Write a C program (compiled with "gcc -xc") similar to the unix "cp" command. In particular, it should take (demand) two arguments, the first the name of the (text) file to be copied, the second the name of the file to contain the copy. For example, if the executable file is stored in "a.out" then the command a.out x y should create in the file 'y' a copy of the file 'x', provided the file 'x' exists. <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< #include void check(int b,char *mess,char *m1, char *m2); int main(int ct,char **arg) {FILE *fin,*fout; char ch; check(ct==3,"Usage: ",arg[0]," "); fin=fopen(arg[1],"r"); check(fin!=NULL,"Failure to open the input file '",arg[1],"'"); fout=fopen(arg[2],"w"); check(fout!=NULL,"Failure to open the output file '",arg[2],"'"); ch=getc(fin); while(ch!=EOF) {putc(ch,fout); ch=getc(fin); } fclose(fout); } void check(int b,char *mess,char *m1, char *m2) {if(!b) {printf("ERROR: %s%s%s\n",mess,m1,m2); exit(1); } } >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 2. Assume that the binary file 'final.dat' contains 10 blocks of data, with each block created from the struct below. Write a C program (compiled with "gcc -xc") that prompts the user for the number of a block and responds by displaying the contents of the struct stored at that block, if the block number is legitimate, where the blocks are numbered 0, 1, 2, ..., 9. struct ABlock {int a; double b; } <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< #include struct ABlock {int a; double b; }; void check(int b,char *mess); int main() {FILE *fin; struct ABlock dat; int block; fin=fopen("final.dat","rb"); check(fin!=NULL,"Failure to open 'final.dat'"); printf("Enter the number of the block- "); scanf("%d",&block); check(block>=0 && block<=9,"Bad block number entered"); fseek(fin,block*sizeof(struct ABlock),SEEK_SET); fread(&dat,sizeof(struct ABlock),1,fin); printf(" a = %d, b = %f\n",dat.a,dat.b); } void check(int b, char *mess) {if(!b) {fprintf(stderr,"ERROR: %s\n",mess); exit(1); } } >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 3. We normally think of a point as a pair of ints (or doubles), but we could generalize the idea to a pair where the first member of the pair is of one type and the second member of the pair is of a second type. Write a template (the declaration and code) for a class called Point whose instances have variables of different types for the two entries. Below is code that should compile and produce the indicated output, given your template. Your template need only have the necessary declarations to enable the code below to compile and run correctly. Point p(true,'a'); cout< > r(7.3,p); cout< template class Point {public: Point(const X & a, const Y & b); Point & setX(const X &a); Point& setY(const Y &b); template friend ostream & operator << (ostream & out,const Point & p); private: X x; Y y; }; template Point::Point(const X & a, const Y & b):x(a), y(b){} template Point &Point::setX(const X &a){x=a; return *this;} template Point& Point::setY(const Y & b){ y=b; return *this;} template ostream & operator << (ostream & out, const Point &p) {out<<"("<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 4. Below is the declaration for the class List, which is meant to maintain a list of integers. Write the declaration and definitions (code) for a sublcass, MyList, that adds the method sort(), which sorts the list in ascending order, and the operator +=, which adds an int to the end of the list. With your class, the sample code should compile and produce the indicated output. class List {public: List(int n=100); //a list of n entries; error if n<1 void add(int n); //add n to the end of the list int length()const; //number of entries in list int capacity()const; //maximum number of entries int & at(int n); //get entry at location n static void check(bool b, char *mess); private: int *data; int max, //maximum number of items in list count; //number of items in list }; MyList p(20); for(int j=0; j<5; j++) p+=(j-2)*(j-2); p.sort(); for(int j=0; j<5; j++) cout< class MyList: public List {public: MyList(int n=100); void sort(); MyList & operator +=(int n); private: void swap(int &a, int &b,bool &c); }; MyList::MyList(int n):List(n){} MyList & MyList::operator +=(int n) {add(n); return *this; } void MyList::sort() {bool sorted; do {sorted=true; for(int j=1; jat(j)) swap(at(j-1),at(j),sorted); } while(!sorted); } void MyList::swap(int & a, int &b,bool &c) {int temp; temp=a; a=b; b=temp; c=false; } >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 5. Write an EASY program that reads in two numbers, assumed to be positive, and displays 1 if the first number evenly divides the second number and displays 0 otherwise, e.g., if the first number is 4 and the second is 13, then 0 is displayed, because 13/4 has a remainder of 1. <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< x y begin read x read y if y/x*x==y goto one write 0 halt one: write 1 halt end 4 13 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 6. Write the MACH1 code that corresponds to the EASY program below. Recall MACH1 operators: read(0), write(1), load(2), store(3), clear(4), add(5), sub(6), mult(7), div(8), addi(9), subi(10), multi(11), divi(12), jumpl(13), jumpg(14), halt(15). x begin read x write (x-4)+(x-3)*(x-2) halt end <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 0 0 0 read 3 14 1 store x 2 14 2 load x 10 4 3 x-4 3 511 4 push x-4 2 14 5 load x 10 3 6 x-3 3 510 7 push x-3 2 14 8 load x 10 2 9 x-2 7 510 10 (x-3)*(x-2) 5 511 11 (x-4)+(x-3)*(x-2) 1 0 12 write result 15 0 13 halt 0 0 14 x E >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 7. Write a class Lex that acts as a lexical analyzer for the list of arguments appearing on the command line, where the items in the language are "{", "}", ",", "...", and IDENT (any string of lower case letters). The analyzer should return one of the Lex constants IDENT (0), LBRACK (1), RBRACK (2), COMMA(3), ELLIPSES(4), and JUNK (5). The code below indicates how the class could be used. int main(int ct,char **arg) {Lex lex(ct,arg); char *toks[]={"IDENT", "LEFTBRACKET", "RIGHTBRACKET", "COMMA", "ELLIPSES", "JUNK"}; cout<<"Here are the tokens on the command line:\n"; while(lex.hasNext()) cout< class Lex {public: static const int IDENT=0, LBRACK=1, RBRACK=2, COMMA=3, ELLIPSES=4, JUNK=5; Lex(int ct, char**arg); bool hasNext(); int next(); private: int count,loc; char **list; }; Lex::Lex(int ct, char **arg):count(ct),loc(1),list(arg){} bool Lex::hasNext(){return loc=count) return JUNK; n=loc; loc++; if(list[n][0]>='a' && list[n][0]<='z')//check for all lower case letters {int k=1; while(list[n][k]!='\0' && list[n][k]>='a' && list[n][k]<='z') k++; if(list[n][k]=='\0') return IDENT; return JUNK; } for(int j=1; j<5; j++) if(strcmp(list[n],vals[j])==0) return j; return JUNK; } >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 8. Below is the contents of the file enigma.cc. Write the output that is displayed on the screen when enigma.cc is compiled and run. #include class A {public: A(int n=0):x(n){} void a(){printf("A::a()\n");} void b(){a(); c();} virtual void c(){printf("A::c()\n");} int x; }; class B : public A {public: B(int n=0):A(n){} void a(){printf("B::a()\n");} void c(){printf("B::c()\n");} }; void foo(A*x,A*y) {x->x++; y->x++;} void bar(B*x,B y) {y.x++; x->x++; } int main() {A a(42); B b; a.b(); b.a(); b.b(); printf("%s\n",b.x>0?"positive":"correct"); foo(&a,&a); printf("%d\n",a.x); bar(&b,b); printf("%d\n",b.x); } <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< A::a() A::c() B::a() A::a() B::c() correct 44 1 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>