CSE2050 Exam #1. Open books, open notes. Name _________________________ 1. The code to the right should leave b int b = 1; set to 1, but instead sets it to 3. Circle if (b = 2); the two errors (2 x 5 pts). b = 3; Answer: The code above is legal and does not generate compiler errors. However, the second line should be: if (b == 2) The = does an assignment. The result is the new value of b, which is interpreted as true, since it is not 0. The ; terminates the if statement. If the condition is true, then the empty statement (;) is executed. The third line is not part of the if statement and is executed regardless of the outcome, in spite of the indentation. 2. Rewrite the function below to use the most efficient and appropriate form of passing parameters and returning (3 x 5 pts). string assign(string a, string b) { return a=b; } For example, assign(x, assign(y, z)); // x=y=z; Answer: string& assign(string& a, const string& b) { return a=b; } a must be passed by reference to modify the argument (-5). b cannot be passed by reference if we are to allow expressions (-5). Pass by value will work but is inefficient (-3). Return can be by reference or const reference. We know this is safe because we return a, which is a reference to an object which existed before assign() was called, and therefore will exist after the return. Return by value is inefficient because it makes a temporary copy which is normally discarded (-3). 3. Write a function that prints the contents of a vector of strings, given its begin() and end() iterators. For example (15 pts), vector v(10); print(v.begin(), v.end()); // Your code Answers (there are many): void print(vector::const_iterator b, vector::const_iterator e) { while (b!=e) cout << *b++ << " "; } The parameters may also be iterator, although const_iterator is preferred because it doesn't allow assignment to *b or *e. Iterators are typically passed by value. If passed by const reference, then b++ wouldn't work and you'd need a local iterator: void print(const vector::const_iterator& b, const vector::const_iterator& e) { for (vector::const_iterator p=b; p!=e; ++p) cout << *p << endl; } Since these are random iterators, you could index them and do arithmetic: void print(vector::iterator b, vector::iterator e) { for (int i=0; i m; cout << m["abc"]; // 0.0, but m.size() is now 1 Answer: map::iterator p=m.find("abc"); if (p!=m.end()) cout << p->second; else cout << 0.0; // Optional Other variations using m.find("abc") are possible, for example, if (m.find("abc")!=m.end()) cout << m["abc"]; 5. Write a statement that calls f() and catches and prints the exception (10 pts). void f() {throw string("oops");} Answer: try { f(); } catch(string x) { cout << x; } 6. Class Degree represents a modulo 360 integer, i.e. it can only have values 0 through 359. There is implicit conversion from int, and a method get() which returns the value as an int. For example, class Degree { private: int val; // May be 0 to 359 public: int get() const {return val;} Degree(int a); // val set to a % 360 }; Degree x(450); // x.val is 90 cout << x.get() << endl; // Prints "90" if (x == 810 && x == x) // true, implicit Degree(810) cout << x << endl; // Prints "90 degrees" On the back of the paper, write: a. Constructor code (not inlined) using an initialization list (10 pts). b. operator << to print the value followed by " degrees" (15 pts). c. operator == as a non-member to compare modulo 360 (15 pts). Answer: Degree::Degree(int a): val(a % 360) {} ostream& operator << (ostream& out, const Degree& b) { return out << b.get() << " degrees"; } bool operator == (const Degree& a, const Degree& b) { return a.get() == b.get(); }