.. _lecture4: Expressions and Interactivity ############################# .. seealso:: Text: Chapter 3 Once we have some data, specifically numerical data, to work with, we need to know what operations we can perform on them. Precedence ********** You should already know about operator precedence. That is the set of rules the language follows when evaluating an expression. In general, we should have learned that multiplication and division always happen before addition and subtraction. Parentheses =========== You should also know that you can force things to be evaluated the way you want is you use parentheses around subexpressions. The system works from the inner-most set of parentheses outward, evaluating subexpressions, and eliminating the parentheses as it works out the final value. Consider this expression: .. code-block:: c (x + y * z - (x - (y / z + 2) * z) + 5) Phew! How will this be processed (and what kind of person invents such an expression?) Here is how it will go: .. code-block:: text (x + y * z - (x - (y / z + 2) * z) + 5) (x + y * z - (x - (r1+ 2) * z) + 5) (x + y * z - (x - r2 * z) + 5) (x + y * z - (x - r3) + 5) (x + y * z - r4 + 5) (x + r5 - r4 + 5) (r6 - r4 + 5) (r7 + 5) r8 The system hunted down the innermost set of parentheses and began evaluating that subexpression. It used normal operator precedence in doing this. When is completed that evaluation, it removed the expressions, and repeated the process looking for more parentheses to work on. It scans the complete expression each time from left to right looking for something to "reduce". When all the parentheses are gone and all operators have been applied we are done. That final answer is what is used as the result of the evaluation. Data Types ********** Remember that C++ is a "strongly typed" language. That means it is serious about protecting data and not letting you mess with their data types. If you set up an integer variable, it will remain an integer variable for the life of the program. So, how is C++ going to deal with something like this: .. code-block:: c int X = 5; float PI = 3.1415926; int Z; Z = X * PI + 2.5; Here, we have two `initialized` variables. The names are recorded, along with the data type specified on each `declaation`. The first two are given an appropriate initial value. The last declaration sets up an `uninitialized` variable. .. warning:: That variable should be assumed to hold a junk value until you specifically place some useful value in it! Failing to remember this leads to errors in your code. The last line is called an `assignment statement`. The `expression` on the right side of the equal sign is `evaluated` and then the resulting value is stored in the named variable on the left side of the equal sign. Simple. But what ends up stored in `Z`? To figure this out, we need to use the `precedence` rules, and learn a simple fact about this kind of math:: If two numbers are combined using a math operator, he resulting value data type will be: * integer if both numbers are integrs. * float if either number (or both) is a float. So, how is this example evaluated? 1. X (`int`) is multiplied by PI (`float`) producing a `float` value. 2. That `float` value is added to 2.5 (`float`) producing another `float`. 3. That `float` final value is stuffed into an `int` container. The system chops off the fractional part converting it into an `integer` and the statement is complete. The conversion from `float` to `integer` is a bit more complex than it seems. Remember how things are `encoded` in the machine. The conversion has to work hard to figure out the precise new pile of binary bits to store in the final container. C++ Operators ************* Here is a list of the standard operators available in C++. Many of these are available in Python, but a few Python operators are not available in C++. Basic Arithmetic Operators ========================== +---------+----------------+ | Operator| Operation | +=========+================+ | ``+`` | addition | +---------+----------------+ | ``-`` | subtraction | +---------+----------------+ | ``*`` | multiplication | +---------+----------------+ | ``/`` | division | +---------+----------------+ | ``%`` | modulo | +---------+----------------+ The ``modulo`` operator gives the integer remainder after division. .. code-block:: text 13 % 4 -> 1 Increment/Decrement Operators ============================= In programming, you often see statements like this: .. code-block:: c x = x + 1; These are so common, C++ provides a shortcut: +---------+----------------+ | Operator| Operation | +=========+================+ | x++ | post increment | +---------+----------------+ | x-- | post decrement | +---------+----------------+ | ++x | pre increment | +---------+----------------+ | --x | pre decrement | +---------+----------------+ Understanding what is going on here is a bit tough. Normally, when you access a variable, you pull out the value stored there and use it in the expression it lives in. In the case of these operators, we still pull out the value stored in the container, but what happens depend on whether the operator is a pre or post one. If it is a post operator, we use the current value stored in the container, then add one to that value and put it back in the named container. That increments the stored value. If it is a pre operator, we pull out the value in the container, add one to it and use that new value in the expression, then we store that new value back in the named container. As if that were not bad enough, this is perfectly legal: .. code-block:: c x = 5; y = ++x--; What ends up in x, or y after these statements are processed? Compound Operators ****************** In the same spirit, there are simplifications for common statements like this: .. code-block:: c x = x * 5; Here are the new operators we can use: +------------+----------------+ | Operator | Operation | +============+================+ | ``x += 5`` | ``x = x + 5`` | +------------+----------------+ | ``x -= 5`` | ``x = x - 5`` | +------------+----------------+ | ``x *= 5`` | ``x = x * 5`` | +------------+----------------+ | ``x \= 5`` | ``x = x \ 5`` | +------------+----------------+ Logical Operators ***************** We need to ask questions, and those questions often ask us to compare two values. Here are the operators we can use: +----------+------------------+ | Operator | Operation | +==========+==================+ | ``==`` | exactly equal to | +----------+------------------+ | ``!=`` | not equal to | +----------+------------------+ | ``>`` | greater than | +----------+------------------+ | ``<`` | less than | +----------+------------------+ | ``>=`` | greater or equal | +----------+------------------+ | ``<=`` | less or equal | +----------+------------------+ Logical Conjunction Operators ============================= We can ask compound logical questions using the logical conjunction operators. There are the logical ``and``, and logical ``or`` operators. We can also use logical ``negation`` (``not``): +----------+-----------------+ | operator | operation | +==========+=================+ | ``&&`` | logical ``and`` | +----------+-----------------+ | ``||`` | logical ``or`` | +----------+-----------------+ | ``!`` | logical ``not`` | +----------+-----------------+ Short Circuit Evaluation ======================== When using these conjunction operators, it is important to remember that once the value of the expression is known, evaluation stops. For instance, if we form this expression: .. code-block:: c (x != 0) && (y / x) It is not safe to perform the division in the second part of this expression if ``x`` has a value of zero. But the first part of this expression checks that. If the value stored in ``x`` is not zero, the first part evaluates to ``true``. The second part needs to be evaluated to determine the final value of the expression. If the value stored in ``x`` is zero, the value of the first part is ``false`` and it does not matter what the second part evaluates to, the result is ``false``, so the processing will stop, and we will not divide by zero, which would cause problems. (what?) Other Operators *************** There are a few other operators available, but they are not commonly used, especially by beginners. We will leave them to a later course. Interaction *********** We do need to figure out how to input things from the user while the program is running. C++ provides this capability using features provided by the ``iostream`` package: .. code-block:: text # include int X; float Y; cin >> X; cin >> Y; The system will pause when it processes this statement, and wait for the user to type something in on the keyboard. Each character will be processed until a character is encountered that is not legal for the data type of the variable we are using to capture the input value. Normally, you should output a ``prompt`, telling the user to enter something. Otherwise they may stare at the screen wondering what is going on! They usually will enter something followed by typing a ``Return`` (or ``Enter``) key. If, instead, they enter a space, that will work, and the system will press on. The second line will be processed, and this time, the program expects a floating point number. .. note:: For floating point numbers, it is possible to enter digits, periods (decimal point), signs, and even "scientific` notation (something like 1.023e-3) The user will see what they entered since the console echoes what they type. It is possible for them to correct a mistake when typing by pressing the backspace key (or delete on a Mac). Validating Input **************** Unfortunately, you cannot trust those "users". They will try to break your program, just for fun. The proper way to handle user input is not to trust them, ever! They may not do what you ask and your program should do something sane if they enter the wrong thing. Instead, you make sure your program can handle whatever they do, and respond appropriately. If you ask them to enter an number and they type "no", you should detect that, and remind them to enter a number. How you do this is something we will explore later. For now, we will do an evil thing, we will "trust" the user while we learn how to write C++ code! (That user will be yu, or me, when we are testing your code!) .. vim:filetype=rst spell: