// General tips // Don't stay up the night before eating Jello and drinking non-alcoholic beer. Or even studying! Your mind needs rest to perform well. Eat breakfast that morning. Be sure to review what the invalid characters for variable names are. Be sure to review operator precedence rules. Know how modulus works. What is 0 % y, where y is any number? What is 24 % 3 ? And 24 % 5 ? // Loops // BE SURE YOU CAN WRITE A FOR LOOP OR WHILE LOOP BY HAND. In class we reinforced how you can write while or for loops that never execute their code blocks. Remember, 'continue' halts the current iteration of the loop and continues processing the loop logic (eg, the for/while terminating condition is checked and the loop runs again or ends if the terminating condition is met). In contrast, 'break' halts the execution of the loop immediately. What's an infinite loop? One whose terminating condition is always true _AND_ whose code block does nothing to change the state of the terminating condition nor explicitly breaks out of the loop. Example: // Will this loop ever stop? Disco! for (int i = 0; true; ++i) { cout << "Aye aye aye: " << i << endl; } // How about this one? for (int i = 0; true; ++i) { cout << "Aye aye aye: " << i << endl; if (i == 10) break; } Now, rewrite this for loop as a while loop: for (int i = 0; i < 10; ++i) { cout << "Do this and ace the final" << endl; } I bet that you can't create a for loop that can't be rewritten as a while loop. (Trust me on this, don't waste your time.) HOWEVER, there are cases where a while loop can't quite be written as a for loop, BUT it requires additional an control structure (eg, if statements). For example: while (counter <= 10) { if (counter == 5) continue; counter++; } You probably can't rewrite that as a for loop. But *without* additional control structures (like the if statement), fors can always become whiles and whiles can always become fors. // File I/O // Remember, in class we always stressed that reading values from a file is dependent on the variable types into which you are reading the data. ifstream >> is picky! int a, b, c; while (myfile >> a >> b >> c) { cout << (a + b + c) << endl; } If the datafile is: 1 2 Will the while loop ever run? (try it in a program!) If the datafile is: 1 3 4 a c e What gets printed to the screen? (try it!) If the datafile is: 5 2.0 4 Does the while loop ever run? (try it!) What if a, b and c are declared as doubles? (try it!) Remember, int data values can be coerced into doubles, but doubles won't be casted into ints. Be sure to try the code above with a simple datafile and change the variable types and the elements in the datafile to witness the effect! // FUNctions // Be sure you can write a function prototype by hand. It will *always* be of the form: return_type name(arg_type arg_name, arg_type arg_name, ...); Do not forget return types, do not forget the semicolon, do not write braces or anything else -- this is a PROTOTYPE. Be sure you can write a function implementation by hand. If you got the prototype right, you should be able to get plenty of partial credit for the implementation because THE PROTOTYPE MATCHES THE FUNCTION HEADER, EXACTLY, ALWAYS, right? With one difference: return_type name(arg_type arg_name, arg_type arg_name, ...) { // implementation } I literally copy/pasted the prototype and replaced the semicolon of the prototype with braces. You should too. Always. // Classes // Be sure you know how to write at least the shell of a class definition. Always: class ClassName { }; Be sure you can define the prototype for a default constructor. class ClassName { public: ClassName(); }; Remember the general pattern of accessors (getters/setters). Given private int member variable x: void setX(const int val); int getX() const; Always! What does the const in the setX() argument list do? What does the const after getX() do? Remember that when implementing class member functions you need to resolve their scope with the :: operator! If I declare a member function "int aceTest() const;" in my class definition, the implementation is always: int ClassName::aceTest() const { return 100; } Again: return_type class_name::func_name(arg_type arg_name, ...) { // logic } Don't forget, prototype MUST match function header always. Don't forget consts. Don't forget &'s. Remember, member function implementations have direct access to all member variables! EXERCISE Define a class Buddy with member variables "string name, int age", accessors for name and age, a default constructor, a two parameter constructer that accepts a string and an int (for name and age). Now write the implementation of the constructors and accessors: default constructor should set name to "Mr. no name" and age to whatever your age is two-param constructor should set name and age to whatever the argument values are accessors should use const where appropriate Now, write a global function called "oldFriend" that has one parameter, a Buddy object passed by reference. The function should return a new Buddy object whose name is the same as the argument passed, but whose age is 30 years higher. Now, write a global, non-friend function "operator>" that uses the member function getAge() to compare the two Buddy objects and return an appropriate value. (hints: what should the return type of all overloaded boolean operators be? does the function modify either of its arguments?) // Arrays // You should absolutely know how to declare an array by hand. Exercises follow: Write a snippet of code that declares an array that can hold 10 doubles. Now set the values of the array elements to numbers: (840, 1260, 1680, ...) -- hint: yes, you need a loop! Write one line of code that declares a 10x10 array whose initial values are all 0. -- hint: I can do this with a one-dimensional array like this: "int gfs_n_bfs[10] = {0};" // Pointers // First, be sure to review the pointers code posted on our site: http://mines.humanoriented.com/classes/2009/fall/csci261/code/pointers.cpp.txt Be sure you know how to dereference a pointer. ("Dereference" can be thought of as "using the value of a variable that is pointed to"). See the code linked above for specifics (I strongly recommend you run/play with that code if you haven't already.) Take special note of how you deallocate memory. To delete a pointer, you usually: int *ages; // ... delete ages; But to delete an array pointer, the proper syntax must be used: int *ages = new int[100]; // delete ages; // NO NO! delete [] ages; // Oh yes! Also, **remember** that the number one problem with pointer-related crashes is array indices going out of bounds.