Remember our round function?
It worked fine for postive nos. but not for negative. The reason is we need to add .5 to a positive no. but subtract .5 from a negative in order to round it.
We can do this by using an if
statement
What this says roughly is
if the expression in parentheses is true
then execute the next statement
otherwise
execute this alternate statement
The
expression
in parentheses is known as a logical expression (or
boolean expression). We need to study logical expressions before we can really
study if
statements.
A logical expression is one which lets us test a relationship between
two operands and express the result as a boolean— that is, true
or false
.
An example is
n < 3
which evaluates to true
if n
is less than 3
and false
if n
is either equal
to or greater than 3
. The symbol <
in this context is known as a relational
operator.
There are six relational operators, all of which take two operands.
operator |
operation |
< |
left operand is less than? right operand |
> |
left operand is greater than? right operand |
<= |
left operand is less thanor equal to? right operand |
>= |
left operand is greater thanor equal to? right operand |
== |
left operand is equal to? right operand |
!= |
left operand is not equal to? right operand |
Again, the outcome of a relational operation is always boolean—true
or false
.
By themselves, the
relational operators
don't allow us to write terribly
interesting functions yet. However, we can combine relationships, using three
special boolean operators. Boolean operators are like relational operators
in that they produce true
or false
results. The difference is that their operands
also have to be boolean.
Operator | Kind | Relationship |
&& | binary | And |
|| | binary | Or |
! | unary | Not |
They correspond to what you would expect and, or and not to mean in ordinary speech. But we can define them more rigorously using a table.
a |
b |
a && b |
a || b |
!a |
false |
false |
false |
false |
true |
false |
true |
false |
true |
true |
true |
false |
false |
true |
false |
true |
true |
true |
true |
false |
a||b
is true
if either a
or b
is true
a&&b
is true
only if both a
and b
are true
Now this lets us construct more interesting expressions such as
test whether n is 3 or between 7 and 10
The equivalent logical expression is
n == 3 || n>= 7 && n<=
10
Of course, if I didn't mean to include the end points when I said 'between' (open interval instead of a closed interval,
n == 3 || n> 7 && n< 10
Notice, for this to work, relational operators have to have a higher precedence
than the boolean operators &&
and ||
, as indeed they do.
Here is a table for the precedence of all the operators we know about so far
Operator | Precedence | Description |
! + - |
Highest | logical not, unary plus, unary minus |
* / % |
multiplication, division, modulo | |
+ - |
addition, subtraction | |
< <= > >= |
relational inequalities | |
== != |
equal, not equal | |
&& |
and | |
|| |
or | |
= |
Lowest | assignment |
Because and (&&
) and or(||
) have a lower precedence than the relational operators,
the relational operations are carried out first. That is, it as if we put in
parentheses as follows:
return (number == 4) || (number >= 7) && (number <= 10)
This makes sense because the relational operators can have non-boolean operands,
but they will produce boolean results. ||
and &&,
however,
require boolean operands (as well as producing boolean results).
So you do the relational operations first, getting all boolean results, then you use the boolean operators to combine those results.
Logicists (or philosophers) would consider the three phrases to be propositions each
of which is either true
of false
Integer types are converted to bool
as follows:
0
is converted to false
true
Integer types include both int
and char
. Note also that since double
s can
be converted to int
s, this effectively means double
s can be converted to bool
as well.
If an int
value occurs where a bool
is expected,
this conversion is often applied automatically, e.g
if (i) x*=i;
else x+=1;
This is generally regarded as poor style.
Note: We haven't actually studied if
yet (next topic!) but the
meaning should be clear.
values of type bool
can be converted to int
as follows:
false
is converted to 0
true
is converted to 1
Again, if a bool
value is encountered where an int
is expected the conversion
can occur automatically. In the following example flag
is a bool
and x
is
a double
:
x = x + flag;
Since x
is a double
and only a double
can be added
to a double
, the value of flag
is first converted
to an int
( 0
or 1
) and then that int
is converted to a double
(0.0
or 1.0
).
If
flag
is false
, x
remains unchanged.
If true
, 1.0
is added to x
.
Such "clever" programming is seldom justified and we will penalize it as bad style.
C++ (and many languages which borrow its syntax such as Java, JavaScript, PHP) have something know as the short-circuit property.
Within the bounds of precedence, boolean expressions are executed left to right. Once the outcome of the expression is known, execution stops with no farther evaluation.
In the above example, the steps are as follows.
number==4
)number >=7
)number <= 10
)if we input to number a value
of 4, the first proposition will be true
. Since that guarantees the entire
combined proposition is true
(true
or anything else is always true
), step 1
is the only step that is executed.
If we input 5 or 6, the first proposition will be false
, proposition
two will be false
, guaranteeing the entire proposition is false
,
so execution stops after step 3.
Let's run this example again, focusing on the short-circuit property.
1. Try editing the code to add a cin
statement just before the return
in main
. Then use it to enter your own data. See if you can get the expression to quit evaluating on any of the terms.
Given four integer variables, A, B, C and D, create functions to do the following:
true
if any of them is negative.true
if A is the smallest value.true
if any pair is equal.true
if the product of any pair is equal to the product of the other pair.bool anyNegative(int A, int B, int C, int D){ return A < 0 || B < 0 || C < 0 || D < 0; }
bool isALeast(int A, int B, int C, int D){ return A < B && A < C && A < D; }
bool anyEquality(int A, int B, int C, int D){ return A == B || A == C || A == D || B == C || B == D || C == D; }
bool productEquality(int A, int B, int C, int D){ return AB == CD || AC == BD || AD == BC; }