Before talking about operators, we'll take a quick aside
into
booleans, since
we'll need to know what a boolean is before discussing
operators. A boolean value is one that can be either
true or false. No other values are allowed. Booleans
and boolean operations are at the heart of programming.
Many times in a program, you'll want to do one thing
if a certain
condition
is true, and a different thing if the condition is false.
For example, when processing a series of checkboxes,
you may want to take an action only if a box is checked,
and do nothing otherwise. That's when you'll want to use
a boolean.
Most programming languages have a type for booleans,
usually called "boolean" or "bool". Some C++ compilers
recognize the type
bool
, others do not.
For now, assume that your compiler supports the
bool
type. We'll discuss what to do
if your compiler doesn't, in a moment.
In order to use boolean logic to your advantage, you
need to learn about the three basic boolean operations.
They are called
and,
or, and
not. Each operation
takes either one or two boolean inputs, and returns
a boolean output. They are
often represented by symbols known as "gates", shown
below.
and |
The "and" operation takes two inputs and produces
one output. If both inputs are true, the output is true;
in all other cases, the output is false. It can be interpreted
as follows: "I will return true if input 1 and input 2
are true." |
or |
The "or" operation takes two inputs and produces
one output. If either of the inputs are true, the output
is true; otherwise (i.e., if neither input is true), the
output is false. It can be interpreted as follows:
"I will return true if either input 1 or input 2
is true." |
not |
The "not" operation takes one input and produces
one output. If the input is true, the output is false.
If the input is false, the output is true. In other words,
the "not" operation takes the input and returns its opposite. |
There are operators in C++ which behave just as the boolean
gates shown above! We'll show you an example of how to use
each one.
and: &&
The "and" operator is used by placing the "and" symbol,
&&
, in between two boolean values.
//suppose that Fran is tired
bool franIsTired = true;
//but Fran doesn't have to wake up early
bool franMustWakeUpEarly = false;
//will Fran go to sleep now?
bool bedTime = franIsTired && franMustWakeUpEarly;
What does this chunk of code do? It initializes two variables,
franIsTired
and
franMustWakeUpEarly
, to
true
and
false
, respectively. Then, in the
third line of code (not including comments!), we determine that Fran
will go to sleep
if and only if the "and" operation is true --
that is, if both inputs to the "and" operation are true. In this
case, the first input is true and the second input is false. Since
"and" requires both inputs to be true in order for the output to be
true, but one of the inputs is false, the output will be false. So,
the variable
bedTime
will store the value
false
.
Also, take note that the variable names used here are lengthy.
How you decide to program is up to you, but often times it's
better to have lengthier variable names that are readable,
rather than short, obfuscated variable names like
"i" or "zz". (The names in this example may have gone
overboard, though.)
or: ||
The "or" operator is used by placing the "or" symbol,
||
, in between two boolean values.
//suppose that Graham is tired
bool grahamIsTired = true;
//but Graham doesn't have to wake up early
bool grahamMustWakeUpEarly = false;
//will Graham go to sleep now?
bool bedTime = grahamIsTired || grahamMustWakeUpEarly;
This example is very similar to the example involving
Fran, except notice the key difference: whether or not
Graham goes to sleep is determined differently. Graham
will go to sleep if he is tired
or if he needs
to wake up early. Whereas Fran would go to sleep
only if both conditions were true, Graham will go to sleep
if either condition (or both) is true. Therefore,
the value of
bedTime
is
true
.
not: !
The "not" operator is used by placing the "not" symbol,
!
, before a boolean value.
//suppose that Julian stayed up late
bool julianStayedUpLate = true;
//will Julian be peppy tomorrow?
bool julianIsPeppy = !julianStayedUpLate;
This example illustrates the "not" operator. At the end
of this block of code, the variable
julianIsPeppy
will take on the opposite value of
julianStayedUpLate
.
If
julianStayedUpLate
were
false
, then
julianIsPeppy
would be
true
. In this
case, the opposite is true, so
julianIsPeppy
gets
a value of
false
.
It is perfectly legal in C++ to use boolean operators on variables
which are not booleans. In C++, "0" is false and any non-zero value
is true. Let's look at a contrived example.
int hours = 4;
int minutes = 21;
int seconds = 0;
bool timeIsTrue = hours && minutes && seconds;
Since
hours
evaluates to
true
, and
since
minutes
evaluates to
true
, and
since
seconds
evaluates to
false
, the
entire
expression
hours && minutes && seconds
evaluates to
false
.
In addition to the boolean operators, C++ has a number
of arithmetic operators. Here they are:
Arithmetic operators |
name |
symbol |
sample usage |
addition |
+ |
int sum = 4 + 7 |
subtraction |
- |
float difference = 18.55 - 14.21 |
multiplication |
* |
float product = 5 * 3.5 |
division |
/ |
int quotient = 14 / 3 |
modulo ("mod") |
% |
int remainder = 10 % 6 |
They all probably look familiar with the exception of
mod (
%
). The mod is simply the remainder
produced by dividing two integers. In the example
shown in the table above, if we treat
10 / 6
as an integer divison, the quotient is 1 (rather than 1.666)
and the remainder is 4. Hence, the variable
remainder
will get the value 4.
You are undoubtedly familiar with equality operators, even if you
don't know it. An equality operator is one that tests a condition
such as "is less than", "is greater than", and "is equal to".
You will find it useful to be able to compare two numbers using
expressions like "x is less than y".
Let's say you are writing software for a bank ATM (automated teller
machine). A customer makes a request for a certain amount of cash,
and your responsibility is to determine if they should be allowed to
withdraw that amount. You could decide to use the following
algorithm:
"if the amount requested
is less than the account balance, that amount should be withdrawn;
otherwise, the customer should be notified and no money should be
withdrawn." Makes sense, right? So, the next step is coming up with
some pseudo-code. Once you have pseudo-code, writing the C++ code
will be easy.
Pseudo-code for the ATM problem might look like this:
if the amount requested < account balance then
withdraw the amount requested
otherwise
withdraw nothing and notify the customer
Now that we have pseudo-code, writing the C++ code is as simple
as "translating" your pseudo-code into C++. In this case,
it's easy:
if (amountRequested < accountBalance) {
withdraw(amountRequested);
}
else {
withdraw(0);
notifyCustomer();
}
You'll notice some new syntax in this example, but don't worry about
it too much. Pay close attention to the very first line, which checks
to make sure that the amount requested is less than the account
balance. The way it works is, if the
expression between parentheses
(
()
) evaluates to
true
, then the first
block of code will be read. That is,
the code inside the first set of curly braces (
{}
) will
be executed. If the expression in parentheses evaluates to
false
, on the other hand, then the second block of code
(the code following the word
else
) will be read. In this
case, the first block of code withdraws the amount requested by the
customer, while the second block of code withdraws nothing, and
notifies the customer.
That wasn't so hard! All we did was take the original English
description of how we would solve the problem, write some pseudo-code
for the English description, and translate the pseudo-code into C++.
Once you know how to use one equality operator, you know how to use
all of them. They all work the same way: they take the expressions on
either side of them, and either return
true
or
false
. Here they are:
Equality operators |
name |
symbol |
sample usage |
result |
is less than |
< |
bool result = (4 < 7) |
true |
is greater than |
> |
bool result = (3.1 > 3.1) |
false |
is equal to |
== |
bool result = (11 == 8) |
false |
is less than or equal to |
<= |
bool result = (41.1 <= 42) |
true |
is greater than or equal to |
>= |
bool result = (41.1 >= 42) |
false |
is not equal to |
!= |
bool result = (12 != 12) |
false |
Believe it or not, you've already been using assignment operators!
Probably the most common assignment operator is the equals sign
(
=
). It is called "assignment" because you are
"assigning" a variable to a value. This operator takes
the expression on its right-hand-side and places it into
the variable on its left-hand-side. So, when you write
x = 5
, the operator takes the expression
on the right,
5
, and stores it in the
variable on the left,
x
.
Remember how the equality operators, like
<
and
!=
, returned a value that indicated the result?
In that case, the return value was either
true
or
false
. In fact, almost every expression in
C++ returns something! You don't always have to use the
return value, though -- it's completely up to you. In the
case of the assignment operators, the return value is
simply the value that it stored in the variable on the
left-hand-side.
Sometimes your code will use the return value to do something useful.
In the ATM example, one line of code was executed if the condition was
true (that is, if the equality operator
returned true). Two
different lines were executed if the condition was false.
Other times, you'll completely ignore the return value, because you're
not interested in it. Take a look at the following code:
int x;
int y;
x = 5;
y = 9;
cout << "The value of x is " << x << endl;
cout << "The value of y is " << y << endl;
int sum;
sum = x + y;
cout << "The sum of x and y is " << sum << endl;
This chunk of code shows why you might want to throw away the return
value of an operator. Look at the third line,
x = 5
.
We're using the assignment operator here to place the value
5
in the variable
x
. Since the expression
x = 5
returns a value, and we're not using it,
then you could say we are ignoring the return value. However, note
that a few of lines down, we are very interested in the return value
of an operator. The addition operator in the expression
x +
y
returns the sum of its left-hand-side and
right-hand-side. That's how we are able to assign a value to
sum
. You can think of it as
sum = (x + y)
,
since that's what it's really doing.
Operator
precedence is covered on the next page.
The other assignment operators are all based on the equals sign, so
make sure you understand that before going on. Here's another
assignment operator:
+=
. How does it work? You might
guess that it has something to do with addition, and something to do
with assignment. You'd be absolutely right! The
+=
operator takes the variable on its left-hand-side and adds the
expression on its right-hand-side. Whenever you see a statement that
looks like the following:
myVar += something;
it is identical to saying the following:
myVar = myVar + something;
That's exactly what it's doing! It's simply a shortcut.
The other common assignment operators are
-=
,
*=
,
/=
, and
%=
. They all
function just like the
+=
operator, except instead of
adding the value on the right-hand-side, they subtract, or multiply,
or divide, or "mod" it.
Just as the simple assignment operator
=
returns the
value that it stored, all of the assignment operators return the value
stored in the variable on the left-hand-side. Here's an example of
how you might take advantage of this return value. It's not used
terribly often, but it can sometimes be useful.
//these four variables represent the sides of a rectangle
int left;
int top;
int right;
int bottom;
//make it a square whose sides are 4
left = top = right = bottom = 4;
All this code does is store the value in each of the four variables
left, top, right,
and
bottom
. How does it
work? It starts on the far right-hand side. It sees
bottom =
4
. So it places the value
4
in the variable
bottom
, and returns the value it stored in
bottom
(which is
4
). Since
bottom =
4
evaluates to
4
, the
variable
right
will also get the value
4
,
which means
top
will also get
4
, which means
left
will also get
4
. Phew! Of course,
this code could have just as easily been written
//these four variables represent the sides of a rectangle
int left;
int top;
int right;
int bottom;
//make it a square whose sides are 4
left = 4;
top = 4;
right = 4;
bottom = 4;
and it would have done the exact same thing. The first way is more
compact, and you're more likely to see it written the first way. But
both ways are equally correct, so use whichever you prefer.