Topics To Cover

Precedence

What happens when an expression like
2 + 3 * 5
is evaluated? Do I get 17 or 25? Well, your math classes should've taught you that 17 is the answer, and indeed that's true in C++ as well.

When you have two different operators in an expression...

the relative precedence of operators is what determines which operation is performed first.

Since * has a higher precedence than +, the expression 2 + 3 * 5 is evaluated like 2 + (3 * 5).

Associativity

But what about when both operators are the same, or both have the same precedence? What happens with the following code?
a / b * c

When you have two operators the same precedence...

the associativity of the operator(s) is what determines which operation is performed first.

The associativity of * and / (which both have the same precedence) is left-to-right, so a / b * c is evaluated as (a / b) * c. This can matter in C++. For example, what does

3 / 4 * 1.5  // <--- (3/4)*1.5 = 0*1.5 = 0
evaluate to? If you're not sure, read about type type conversion covered in the previous lecture.

Programming Tip:

Always use parentheses rather than relying on subtle precedence and associativity rules!

This table lists the operators and their associativities. They are grouped together on lines with operators of the same precedence, and the lines go from highest precedence at the top, to lowest at the bottom. You should know about precedence and associativity, and you should be able to use tables like this to fix precedence and associativity related bugs, but rely on parentheses when you're unsure.

Left-to-right associativity: cin and cout

Associativity matters. An expression like
cout << 3.0 << " percent"
relies on associativity of the << operator to make sense. Why? Of course, cin >> expressions work the same way.

Right-to-left associativity: assignment

Associativity also makes expressions like
a = b = 0
do what you want. Only in this case = is is right-to-left associative, so we get
a = (b = 0)
The key here is that an assignment expression evaluates to the value of the left-hand-side object after the assignment. Therefore:
  1. b gets assigned value zero, the expression has value zero;
  2. then that's what is assigned to a.

If statements

The ability to make decisions and react to different input is a key part the power of computers. For example, we would certainly expect it to be possible to write a program that works as follows:

A program that reads in a number and

In C++ (as in English!) "if" is the key to expressing this. The program would be written like the code snippet below. Of course we've got to figure out some C++ that will do the "k is even" for us.


cin >> k;
if (k is even)
{
  cout << "even" << endl;
}
else
{
  cout << "odd" << endl;
}
What's inside the ()'s in an if statement needs to be an expression that evaluates to type bool. This is called the test condition. In particular:
  • If the expression evaluates to true, the first block of code (code surrounded by {}'s forms a block) is executed.
  • Otherwise, the block following the else is executed.

int k;
cin >> k;
if ((k % 2) == 0)
{
  cout << "even" << endl;
}
else
{
  cout << "odd" << endl;
}
Now, let's write the C++ code for this test condition.
  • A number is even if 2 divides it evenly, i.e. if its remainder when divided by 2 is 0.
  • So for k to be even, k % 2 must be zero. We can test this using the == operator.
Thus, (k % 2) == 0 is the test condition we need.

Note: A single "=" in C++ is used for assigning values to variables, a double "=" (i.e. ==) is used to test whether two values are equal. A "==" expression evaluates to an object of type bool that is true if the left and right-hand expressions are equal, and false otherwise.

Relational Operators

The "==" is an example of a relational operator. Relational operators make comparisons of their left and right-hand arguments, and return bool values accordingly. They are:
== (equal), != (not equal), <  (less than), >  (greater than),
<= (less than or equal to),  >= (greater than or equal to)

Shortcut: Dropping the Else

Write a program: Read an int from the user and we want to change it to its absolute values and print it out.

int k;
cin >> k;

if (k < 0)
{
  k = -1*k;
}
else
{
  // nothing to do!
}

cout << k << endl;

int k;
cin >> k;

if (k < 0)
{
  k = -1*k;
}





cout << k << endl;
Sometimes you have a condition which, if it's true, should cause you to do some extra work, but which, if it's false, should have no effect on the program. We'd probably write something like the code snippet on the left.

However, when there's nothing to do in the else-block, we can simply drop it, as shown on the right.

Sometimes your if-statement is written so that the then-block is empty and the else-block isn't. You can't simply drop the then-block, so first rewrite your if-statement with a new condition so that the then-block contains the work.

Mandatory Practice Problems

  1. Write a program that reads in a temperature in the form of NUMBER UNITS (e.g "123.02 Fahrenheit" or "-75.0 Celsius") and returns "Gas", "Liquid", or "Solid" depending on the state of H20 at that temperature. Note: We'll assume standard pressure.

    At standard pressure, we have ice at or below 32 Fahrenheit (0 Celsius), steam above 212 Fahrenheit (100 Celsius), and water in between.

    Tip: You need to use nested if statements.

    Sample Run:

    $ ./a.out
    Enter temperature (NUMBER UNITS): 123.02 Fahrenheit
    Liquid
    $ ./a.out
    Enter temperature (NUMBER UNITS): 31.88 Fahrenheit
    Solid
    $ ./a.out
    Enter temperature (NUMBER UNITS): 300.33 Fahrenheit
    Gas
    $ ./a.out
    Enter temperature (NUMBER UNITS): -10.3 Celsius
    Solid
    $ ./a.out
    Enter temperature (NUMBER UNITS): 31.88 Celsius
    Liquid
    $ ./a.out
    Enter temperature (NUMBER UNITS): 123.02 Celsius
    Gas
    
    Solution: Determining the state of H20.

Other Practice Problems

  1. Converting 12-hour clock time to 24-hour clock time. Here is a first try at solving this problem. Can you see what's wrong? (Try input 10:02AM.) Here are two different solutions to this problem: Version 1 and Version 2.
  2. Real & Complex Roots of a Quadratic Polynomial