=====
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.