CS 228 lecture -*- Outline -*- * translation from Scheme to C++ (or fundamental C++) (H&R Appendix A) ** expressions *** translations ---------------- EXPRESSION TRANSLATIONS Scheme: (myfunction 3 4) C++: myfunction(3,4) Scheme: (+ 2 3) C++: 2 + 3 Scheme: (* (+ 2 2) 7) C++: (2 + 2) * 7 Scheme: (add1 i) C++: i + 1 Scheme: (sub1 i) C++: i - 1 Scheme: (/ (mod 44 6) 2) C++: (44 % 6) / 2 ---------------- note that / above is integer division, not generally exact as in Scheme Q: what is another way to write (a + b) * (a - b) in C++? Q: what is the quadratic formula? quadratic formula gives solutions to ax^2 + bx + c = 0 (-b + sqrt(b^2 - 4ac))/2a Q: can you write down the quadratic formula in C++? (-b + sqrt(b*b - 4*a*c))/2*a Discuss the parentheses when might this not work? if a == 0, or if b^2 -4ac is negative *** example ------------------- PROBLEM Write a program to read in a, b, c, and print the two roots of ax^2 + bx + c = 0 ------------------- develop this **** psuedo-code SNAPSHOT 1 // quadratic.C // Name: Gary T. Leavens // TA: Bjarne Stroustrup // Section: A1 #include int main() // MODIFIES: cin, cout // POST: cout has prompts for a, b, and c written to it, // and after each prompt, the corresponding double is read from cin; // finally cout has the two roots printed. { double a, b, c; // read in a, b, and c // print the positive root // print the negative root return 0; } **** first draft for now, let's ignore that a might be 0 (otherwise it's not quad.) SNAPSHOT 2 // quadratic.C // Name: Gary T. Leavens // TA: Bjarne Stroustrup // Section: A1 #include #include "prompt.h" int main() // MODIFIES: cin, cout // POST: cout has prompts for a, b, and c written to it, // and after each prompt, the corresponding double is read from cin; // finally cout has the two roots printed. { double a, b, c; // read in a, b, and c prompt("a? "); cin >> a; prompt("b? "); cin >> b; prompt("c? "); cin >> c; // print the positive root cout << (-b + sqrt(b*b - 4*a*c))/2*a; // print the negative root cout << (-b - sqrt(b*b - 4*a*c))/2*a; return 0; } **** fixing type errors Q: where should we get the declaration for sqrt? need to #include SNAPSHOT 3 // quadratic.C // Name: Gary T. Leavens // TA: Bjarne Stroustrup // Section: A1 #include #include #include "prompt.h" int main() // MODIFIES: cin, cout // POST: cout has prompts for a, b, and c written to it, // and after each prompt, the corresponding double is read from cin; // finally cout has the two roots printed. { double a, b, c; // read in a, b, and c prompt("a? "); cin >> a; prompt("b? "); cin >> b; prompt("c? "); cin >> c; // print the positive root cout << (-b + sqrt(b*b - 4*a*c))/2*a; // print the negative root cout << (-b - sqrt(b*b - 4*a*c))/2*a; return 0; } **** fixing load error (on Unix) need to use the math library -lm **** domain error doesn't work for inputs like 4.5, 3.2, 5.1 for inputs of 100, 3, 0 shows need more formatting. we'll fix this later, when we get to "if" **** labeling the outputs label the outputs, leave out the semicolons, etc. Note for next year, a better label for the output would be: cout << "(-b + sqrt(b*b - 4*a*c))/2*a is: "; SNAPSHOT 4 // quadratic.C // Name: Gary T. Leavens // TA: Bjarne Stroustrup // Section: A1 #include #include #include "prompt.h" int main() // MODIFIES: cin, cout // POST: cout has prompts for a, b, and c written to it, // and after each prompt, the corresponding double is read from cin; // finally cout has the two roots printed. { double a, b, c; // read in a, b, and c prompt("a? "); cin >> a; prompt("b? "); cin >> b; prompt("c? "); cin >> c; cout << "The positive root: "; cout << (-b + sqrt(b*b - 4*a*c))/2*a << endl; cout << "The negative root: "; cout << (-b - sqrt(b*b - 4*a*c))/2*a << endl; return 0; } **** avoiding recomputation (and prompting) Q: how can we avoid the redundancy? function for prompting, with argument Q: how can we avoid the repeated compuations? variables, this is like LET in Scheme SNAPSHOT 5 // quadratic.C // Name: Gary T. Leavens // TA: Bjarne Stroustrup // Section: A1 #include #include #include "prompt.h" int main() // MODIFIES: cin, cout // POST: cout has prompts for a, b, and c written to it, // and after each prompt, the corresponding double is read from cin; // finally cout has the two roots printed. { double a, b, c; // read in a, b, and c prompt("a? "); cin >> a; prompt("b? "); cin >> b; prompt("c? "); cin >> c; double discriminant = b*b - 4*a*c; double a_twice = 2*a; double minus_b = -b; double sqrt_d = sqrt(discriminant); cout << "The positive root is: "; cout << (minus_b + sqrt_d)/(a_twice) << endl; cout << "The negative root is: "; cout << (minus_b - sqrt_d)/(a_twice) << endl; return 0; } Have them suggest inputs, or ... Q: can you write a program that inputs two numbers, and prints their sum and difference? *** type coercion (HR A.8) Q: how did we get away with writing 2*a? 2 is an int but a was a double ------------------------ TYPE PROMOTION (WIDENING) value of smaller type --> value of larger int i = 5; double d = i; // d is 5.0 idea: char --> short --> int --> long --> float --> double --> long double No problems: short --> int --> long unsigned short --> unsigned int --> ... float --> double --> long double Usually safe (may approximate): int --> float int --> double ... -------------------- These may approximate if can't fit all the significance into the float -------------------- Machine dependent: char --> short char --> int ------------------- Behaves differently depending on whether on not chars are signed. Moral: don't use char as a short number, use signed char or unsigned char if need be. *** type casting (HR A.9) can make coercions visible ------------------------ TYPE CAST functional notation: int i = 5; double d = double(i); parentheses notation: unsigned int ui = 5U; unsigned long x = (unsigned long) ui; ------------------------ need to use the latter when have a two-word name like "unsigned long". No semantic difference vs. implicit coercion but can "see" more of the cost (instructions are executed) Q: can you write the roots program with type casts? may be easier to use 2.0 and 4.0 instead of the casts. ** statements and control structures (HR A.13) *** translations **** assignment --------------------------- STATEMENT TRANSLATIONS Scheme: (set! i 3) C++: i = 3; ------------------------- caution: it's easy to confuse this with the C++ equality test == single most common mistake... pronounce this "i gets 3" **** conditionals ------------------------ Scheme: (if (> x 0) (set! s 1) (set! s 0)) C++: if (x > 0) { s = 1; } else { s = 0; } Scheme: (if (< x 0) (writeln "x negative")) C++: if (x < 0) { cout << "x negative" << endl; } ------------------------ you don't always need the { and }, but best to always use them ------------------------ STATEMENT TRANSLATIONS 2 Scheme: (cond ((> (f x) 0) (set! s 1)) ((= (f x) 0) (set! s 0)) (else (set! s -1))) C++: if (f(x) > 0) { s = 1; } else if (f(x) == 0) { s = 0; } else { s = -1; } ---------------------- Note the use of == above, definitely not = the formatting is a convention ---------------------- Scheme: (case e ((1 2 3) (set! x 1)) ((4 5 6) (set! x 2)) (else (set! x 3))) C++: switch (e) { case 1: case 2: case 3: x = 1; break; case 4: case 5: case 6: x = 2; break; default: x = 3; break; } ------------------------------ explain the semantics of switch, works for any integral type, including char the statement is actually more general, but best to think of break as part of the syntax. compiles into indirect jump table **** watch out! -------------------------- MOST COMMON AND PAINFUL C++ ERROR int alpha; alpha = 5; if (alpha = 3) { cout << "alpha is 3\n"; } else { cout << "alpha isn't 3\n"; } ------------------------- explain what counts as true (non-zero) and false (0) explain the value of an assignment expression **** quadratic with test to see if root is negative Q: what was a lingering problem with the quadratic formula program? it didn't handle complex roots. Let's print an error message when b^2 - 4ac is negative Note, errors should go to cerr, not cout. Both usually wind up on the terminal. SNAPSHOT 6 // quadratic.C // Name: Gary T. Leavens // TA: Bjarne Stroustrup // Section: A1 #include #include #include "prompt.h" int main() // MODIFIES: cout, cin, cerr // ** changed // POST: cout has prompts for a, b, and c written to it, // and after each prompt, the corresponding double is read from cin; // If the roots are real, cout has the two roots printed, // ** changed // otherwise an error message is printed. // ** changed { double a, b, c; // read in a, b, and c prompt("a? "); cin >> a; prompt("b? "); cin >> b; prompt("c? "); cin >> c; double discriminant = b*b - 4*a*c; if (discriminant < 0) { // ** changed, also below cerr << "Roots are complex" << endl; return 1; } else { double a_twice = 2*a; double minus_b = -b; double sqrt_d = sqrt(discriminant); cout << "The positive root is: "; cout << (minus_b + sqrt_d)/(a_twice) << endl; cout << "The negative root is: "; cout << (minus_b - sqrt_d)/(a_twice) << endl; return 0; } } ***** variations another way to do this would be to set a return code, so return would be outside of the loop. discuss whether the other decls should be inside the else or not. (if time): Show how to use script on this. ***** student exercise ----------------------- FOR YOU TO DO Write a program that inputs 2 integers and outputs their maximum. (Use if.) Include all comments, etc., as for a homework (or test). ----------------------- Then have them compare with someone sitting near them. Put some on the board? **** other simple statements ----------------------- OTHER C++ STATEMENTS declaration: int i; double d = 3.14159; null: ; expression: cout << 3 << endl; ----------------------- the expressions are executed for their side-effects (as in Scheme) *** loop statements ---------------------- LOOPS IN C++ while (n > 1) { if (odd(n)) { n = (3 * n + 1) / 2; } else { n = n / 2; } } do { if (odd(n)) { n = (3 * n + 1) / 2; } else { n = n / 2; } } while (!(n == 1)); // i.e., (n != 1) for (int i = 0; i < 20; i = i+1) { myarray[i] = 0.0; } ---------------------- explain semantics, definite vs. indefinite iteration draw pictures of variables and show how they work **** example: quadratic with loop to input until user stops forgot to do this in Spring 95... **** example: program which prints numbers from 1 to 10 in order write it out in front of students...