===== CS 111 - Week 9 Lecture 1 - 2024-10-22 ===== ===== TODAY WE WILL: ===== * announcements * continue intro to C++ * named constants * C++ (non-main) functions * prep for next class ===== * should be working on Homework 7! ===== reminder: C++ identifier ===== * name a programmer chooses * for example, for a named constant, a function name, a parameter... * in C++: MUST start with a letter followed by 0 or more letters, digits, or underscores _ * no blanks! no tabs! no newlines! * AS in Racket, we have CS 111 course STYLE standards for our identifier choices: * want 'em meaningful! descriptive! not too generic! not misleading! * named constants: ALL-UPPERCASE * parameters and function names: start with a lowercase letter ===== FOR EXAMPLE -- which of the following are syntactically-correct C++ identifiers? ==== 1st_prize // NOPE! can't start with a digit prize2 // OK! third-prize // NOPE! no dash allowed fourth prize // NOPE! no blank in a single identifier name string // NOPE! don't use something already declares // in the same scope a_string // OK! ==== C++ named constants ==== * in Racket: (define MY-CONST expr) * in C++: const desired_type MY_CONST = expr; * the expr needs to be compatible with the desired_type * this is a statement in C++, so it ends with a semicolon * the = operator here is for ASSIGNMENT -- assigning a value TO this named constant (giving it a value) * and the const means the compiler will NOT let its value ever be changed after its initial assignment const int NUM_QUIZZES = 5; * now NUM_QUIZZES is a simple expression of type int, and its value is 5 const double PI = 3.14159; * now PI is a simple expression of type double, and its value is 3.14159 const string SALUTATION = "Dear "; * now SALUTATION is a simple expression of type string, and its value is "Dear " converted to a string ===== reviewing some of C++'s kinds of compound expressions (and some quirks to be aware of!) ===== * say I have parameters quant and unit_cost in C++, what compound expression could be their product? quant * unit_cost * what if I have parameters quant1 and quant2, and I want the average of those two? (quant1 + quant2) / 2 * here, MUST have the ( ) to do the addition before the division, because / has higher operator precedence than + * remember: C++ determines the type of + - * / by the types of its operands * if BOTH are double? you get the double version of that operation * if EITHER ONE is double, you also get the double version of that operation * if BOTH are int, you get the int version of that operation * and C++ does have modulo -- it uses the operator % and it DOES require int operands; * C++ has > <= < >= BUT!!!!! * == is used as the comparison operator for equality! * 3 == (1 + 2) // this is fine, will be true if // 3 and (1 + 2) have the same value * 3 = (1 + 2) // ERROR!! can't assign to a literal 3! * ! not // BOTH are acceptable in C++ for logical not operation * these are PREFIX operators (go BEFORE their single operand) * ! true not false * && and // BOTH are acceptable in C++ for logical and operation * these are infix operators * true && false false and true * || or // BOTH are acceptable in C++ for logical or operation * these are infix operators * true || false false or true ===== * BE CAREFUL with INTERVALS!!! ===== < > <= >= == != all have just TWO operands! IF you write something like a < b < c ...C++ computes a < b, then compares the resulting true or false to c...! EX: if you have a parameter temp, and want to know if temp is in (190, 212), this DOES NOT WORK: 190 < temp < 212 * well, it compiles! BUT it will *always* be true, no matter what temp is! Why? because 190 < temp will be computed first, and it will be either true or false -- and C++ will treat true as 1 and false as 0 in the comparison with 212 -- and since 0 < 212 and 1 < 212 are both true, you'll ALWAYS get true! THIS DOES WORK: (190 < temp) && (temp < 212) * if you realize you want BOTH of two things to be true, you typically want and/&& if you realize you want EITHER of two things to be true, you typically want or/|| ==== C++ (non-main) function definitions! ==== * STILL USING THE DESIGN RECIPE to DESIGN THESE!!!! ===== * so: what's a C++ signature comment? same as a Racket signature comment, except in a C++ comment and using C++ types Racket: ; signature: circ-area: number -> number C++: // signature: circ_area: double -> double ===== * so: what's a C++ purpose statement comment? * STILL *describes* what the function expects, STILL *describes* what the function returns, (and IF it has side-effects, it still *describes* them) * just in a C++ comment instead of in a Racket comment Racket: ; purpose: expects a circle's radius, ; and returns that circle's area C++ // purpose: expects a circle's radius, // and returns that circle's area ==== * next is the function header -- C++ is strongly-typed, so its function header, in addition to defining the function's and parameters' names, ALSO must include their TYPES (function's return type and parameters' types) ...and the C++ function's return type goes BEFORE the new function's name ...and the function name is FOLLOWED by parentheses, inside which any parameters are each declared, each parameter's type followed by the parameter's name, (and separate parameter declarations with a comma) in Racket: (define (circ-area radius) (define (rect-area len wid) in C++: double circ_area(double radius) double rect_area(double len, double wid) ==== after writing the function header, BEFORE completing the function body, write at least two tests, (or more depending on the data involved) ==== * BUT, we will write the tests as bool expressions, with the left operand being the desired example function call and (typically) comparing that to the hoped-for result if it is working (and sometimes additional description of side-effects) my_funct(ex_arg, ex_arg) == (expected_expr) abs(my_funct(ex_arg, ex_arg) - (expected_expr)) < desired_limit * often we'll use ==: circ_area(10) == (3.14159 * 10 * 10) * except when double values make == not work! Then we'll write a boolto see if the actual and expected values are "close enough": abs(circ_area(10) - (3.14159 * 10 * 10)) < 0.001 * in CS 111 class style standards, where are you going to PUT these tests? * during the design recipe steps, you put these IN a comment AFTER the purpose statement: /*=== signature: circ_area: double -> double purpose: expects a circle's radius, and returns that circle's area tests: circ_area(10) == (3.14159 * 10 * 10) circ_area(5) == (3.14159 * 5 * 5) ===*/ double circ_area(double radius) * ...remember, develop and type these in *BEFORE* you finish the function body! * then, at some point, BEFORE you try to compile and run, you will also PASTE these into a cout statement inside of a main function you write for testing purposes; We'll talk about C++'s version of a function body, and how to set up a main function for testing purposes, in class on THURSDAY.