2 + 3 * 5is 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.
Since * has a higher precedence than +, the expression 2 + 3 *
5
is evaluated like 2 + (3 * 5)
.
a / b * c
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
evaluate to? If you're not sure, read about type type conversion
covered in the previous lecture.
However ...
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.
cout << 3.0 << " percent"
relies on associativity of the <<
operator to make
sense. Why?
cout << x
produces an object (with type and
value!), just as evaluating expressions usually do, and that object is in
fact cout
.
Of course, we concentrate on the side effect that evaluating this
expression has, which is to send output to standard out. However, the
fact that the object produced by the evaluation is actually cout itself is
important.
<<
is left associative, i.e. is evaluated left-to-right. So,
cout << 3.0 << " percent"
is evaluated as:
(cout << 3.0) << " percent"
In other words,
cout << "percent"
left to evaluate, which has the desired side effect of printing
" percent" to the screen after 3.0.
cin >>
expressions work the same way.
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:
In C++ (as in English!) "if" is the key to expressing this. The program would be written like the code snippet on the right. Of course we've got to figure out some C++ that will do the "k is even" for us.
if
statement needs to be an
expression that evaluates to type boolean. 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. This is called the test
condition.
k
to be even, k % 2
must be zero. We can test this using the ==
operator. 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. Thus, (k %
2) == 0
is the test condition we need.
int k;
cin >> k;
if ((k % 2) == 0)
{
cout << "even" << endl;
}
else
{
cout << "odd" << endl;
}
"even"
if k
is even and "odd"
otherwise. Then, after the if-statment, we'll do the printing. We
might implement it like this:
if ((k % 2) == 0)
{
string s;
s = "even";
}
else
{
string s;
s = "odd";
}
cout << s << endl;
However, when we try to compile this the compiler complains as follows:
s
is an undeclared identifier
.
s
at all.
Well, as far as the compiler is concerned when it processes the
"cout << s << endl;
" statement, we
haven't defined s
. The problem is caused by the
scope of variables in C++.
}
that closes off the innermost block in which it
was declared.
So the s
that we define inside the else-block is
invisible, is unknown, does not exist outside of that else-block. In
particular, this is true for our cout
-statement. The
scope of a variable is the portion of the code that "sees" the
variable, i.e. that knows it exists. The scope of a variable ends
with the innermost block in which it was defined.
To fix up this version of our even/odd programm, we simply need to
move the declaration of s
outside of the if/else-blocks
so that its scope extends to cout
statement. This'll
work:
string s; // Now, the scope of s is global
if ((k % 2) == 0)
{
s = "even";
}
else
{
s = "odd";
}
cout << s << endl;
==
" 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)As you can see from the operator precedence table, they have lower precedence than the arithetic operators, so things like
2*k > k + 5
do what we'd like them to do - they evaluate the arithmetic expressions on
the left and right, then they apply the ">" operator to compare
the two values. This means, for example, that instead of writing
((k % 2) == 0)
we could write (k % 2 == 0)
and
get the same result.
So what happens when we compare objects of different type? For
example, what happens with k == x
, where k is an int, and x
is a double? The answer is that the same automatic type
conversions are applied as in arithmetic expressions. So, k is
implicitly converted to a double, and this double value is compared to x.
Thus, 5 == 5.2 is false, since 5 is converted to 5.0 prior to the
comparison, and we end up actually doing 5.0 == 5.2.
if
is
followed by a block (the then block) and the else is followed by
a block (the else block). You've already seen one example of a
block: The block following main()
. Anything you can write
inside of the main
block, you can write inside of any block.
This means that our if blocks and else blocks can declare variables,
read input, make assignments to variables ... anything.
So, suppose I wanted to write a program that works as follows:
My program might look something the code on the right, where
Code for circle area | Code for triangle area |
|
|
Each of these "miniprograms" can be placed in its appropriate block, and we get the whole program.
For example:
int
from the user
and we want to change it to its absolute values and print it out.
We'd probably write something like the code snippet on the right. When there's nothing to do in the else-block, we can simply drop it, as shown below.
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.
int k;
cin >> k;
if (k < 0)
{
k = -1*k;
}
cout << k << endl;
10:02AM
.) Here are two different
solutions to this problem: Version 1 and Version 2.