Operators
C++ is rich in built-in operators. An operator
is a symbol that tells the compiler to
perform specific mathematical or logical manipulations. C++ has three
general classes of operators: arithmetic,
relational and logical,
and bitwise.
In addition, C++ has some special operators
for particular tasks. This chapter will examine the arithmetic,
relational, and logical operators, reserving the more advanced
bitwise operators for later.
Arithmetic Operators
Table
3-4 lists the arithmetic operators allowed in C++. The operators +,
–,
*,
and /
all
work the same way in C++ as they do in any other computer language
(or algebra, for that matter). These can be applied to any built-in
data type allowed by C++. When /
is applied to an integer or a character, any remainder will be
truncated; for example, 10/3 will equal 3 in integer division.
The modulus operator %
also works in C++ in the same way that it
does in other languages. Remember that the modulus operation yields
the remainder of an integer division. This means that the%cannot
be used on type float
or double.
The following program illustrates its use:
#include <iostream>
using namespace std;
int main()
{
int x, y;
x = 10;
y = 3;
cout << x/y; // will display 3
cout << "\n";
cout << x%y; /* will display 1, the remainder of
the integer division */
cout << "\n";
x = 1;
y = 2;
cout << x/y << " " << x%y;
// will display 0 1
return 0;
}
The reason the last line prints a 0 and 1 is because 1/2
in integer division is 0, with a remainder of 1. Thus, 1%2 yields the
remainder 1. The unary minus, in effect, multiplies its single
operand by –1. That is, any number preceded by a minus sign
switches its sign.
Increment and Decrement
C++ has two operators not found in some other computer
languages. These are the increment and decrement operators, ++
and – –.
These operators were mentioned in passing in Chapter 2, when the for
loop was introduced. The ++
operator adds 1 to its operand, and –
– subtracts 1. Therefore,
x = x+1;
is the same as
++x;
and
x = x-1;
is the same as
--x;
Both the increment and decrement operators can either
precede (prefix) or follow (postfix) the operand. For example:
x = x+1;
can be written as
++x; // prefix form
or as
x++; // postfix form
In the foregoing example, there is no difference whether
the increment is applied as a prefix or a postfix. However, when an
increment or decrement is used as part of a larger expression, there
is an important difference. When an increment or decrement operator
precedes its operand, C++ will perform the corresponding operation
prior to obtaining the operand’s value for use by the rest of the
expression. If the operator follows its operand, then C++ will obtain
the operand’s value before incrementing or decrementing it.
Consider the following:
x
= 10;
y
= ++x;
In this case, y
will be set to 11. However, if the code is
written as
x
= 10;
y
= x++;
then y
will be set to 10. In both cases, x
is still set to 11; the difference is when it
happens. There are significant advantages in being able to control
when the increment or decrement operation takes place. Most C++
compilers create very fast, efficient object code for increment and
decrement operations that is better than the code generated when the
corresponding assignment
statement is used. Therefore, it is a good idea to use
increment and decrement operators when you can. The precedence of the
arithmetic operators is shown here:
highest ++
– –
– (unary minus)
* / %
lowest +
–
Operators on the same precedence level are evaluated by
the compiler from left to right. Of course, parentheses may be used
to alter the order of evaluation. Parentheses are treated by C++ in
the same way that they are by virtually all other computer languages:
They force an operation, or a set of operations, to have a higher
precedence level.
How C++ Got Its Name
Now that you understand the full meaning behind the ++
operator, you can probably guess how C++ got
its name. As you know, C++ is built upon the C language. C++ adds
several enhancements to C, most of which support object-oriented
programming. Thus, C++ represents an incremental
improvement to C, making the addition of the
++ (the increment
operator) to the name C a fitting name for
C++. Bjarne Stroustrup initially named C++ “C with Classes.”
However, at the suggestion of Rick Mascitti, Stroustrup later changed
the name to C++. While the new language was already destined for
success, the adoption of the name C++ virtually guaranteed its place
in history because it was a name that every C programmer would
instantly
recognize!
Relational and Logical Operators
In the terms relational
operator and logical
operator, relational refers to the
relationships that values can have with one another, and logical
refers to the ways in which true and false
values can be connected together. Since the relational operators
produce true or false results, they often work with the logical
operators. For this reason, these operators will be discussed
together here. The relational and logical operators are shown in
Table 3-5. Notice that in C++, not
equal is
represented by != and
equal is
represented by the double equal sign, ==.
In Standard C++, the outcome of a relational or logical expression
produces a bool result.
That is, the outcome of a relational or logical expression is either
true or
false.
For older compilers, the outcome of a relational or logical
expression will be an integer value of either 0 or 1. This difference
is mostly academic, though, because C++ automatically converts true
into 1 and false
into 0, and vice versa. The operands for a
relational operator can be of nearly any type, as long as they can be
compared. The operands to the logical operators must produce a true
or false result. Because any non-zero value is true and zero is
false, the logical operators can be used with any expression that
evaluates to a zero or non-zero result.
The logical operators are used to support the basic
logical operations AND, OR, and NOT, according to the following truth
table. The table uses 1 for true and 0 for false.
Although C++ does not contain a built-in exclusive-OR
(XOR) logical operator, it is easy to construct one. The XOR
operation uses this truth table:
In words, the XOR operation produces a true result when
one, and only one, operand is true. The following function uses the
&& and
|| operators
to construct an XOR operation. The result is returned by the
function.
bool xor(bool a, bool b)
{
return (a || b) && !(a && b);
}
The following program uses this function. It displays
the results of an AND, OR, and XOR on the values you enter.
(Remember, one will be treated as true and zero is false.) //
This program demonstrates the xor() function.
#include <iostream>
using namespace std;
bool xor(bool a, bool b);
int main()
{
bool p, q;
cout << "Enter P (0 or 1): ";
cin >> p;
cout << "Enter Q (0 or 1): ";
cin >> q;
cout << "P AND Q: " << (p &&
q) << '\n';
cout << "P OR Q: " << (p || q) <<
'\n';
cout << "P XOR Q: " << xor(p, q)
<< '\n';
return 0;
}
bool xor(bool a, bool b)
{
return (a || b) && !(a && b);
}
Here is a sample run produced by the program:
Enter P (0 or 1): 1
Enter Q (0 or 1): 1
P AND Q: 1
P OR Q: 1
P XOR Q: 0
In the program, notice that although the parameters to
xor( ) are
specified as type bool,
integer values are entered by the user. As was just explained, this
is allowed because C++ automatically converts 1 values into true and
0 into false. When the bool
return value of xor(
) is output, it is automatically converted
into either 1 or 0, depending upon whether the outcome of the
operation is true or false. As a point of interest, it is also
possible to specify the return type and parameters of xor
( ) as int,
and the function would work exactly the same. Again, this is because
of C++'s automatic conversions between integer values and Boolean
values. Both the relational and logical operators are lower in
precedence than the arithmetic operators. This means that an
expression like 10 > 1+12 is evaluated as if it were written 10 >
(1+12). The result is, of course, false. Also, the parentheses
surrounding p &&
q and p
|| q in the preceding program are necessary
because the &&
and ||
operators are lower in precedence than the output operator. You can
link any number of relational operations together by using logical
operators. For example, this expression joins three relational
operations:
var>15 || !(10<count) && 3<=item.
Expressions
Operators, literals, and variables are constituents of
expressions. You
probably already know the general form of expressions from your other
programming experience or from algebra. However, there are a few
aspects of expressions that relate specifically to C++; these will be
discussed now.
Type Conversion in Expressions
When literals and variables of different types are mixed
in an expression, they are converted to the same type. First, all
char and
short int values
are automatically elevated to int.
This process is called integral
promotion. Next, all operands are converted
"up" to the type of the largest operand. This is called
type promotion, and
is done on an operation-by-operation basis. For example, if one
operand is a int and
the other a long int,
then the int is
promoted to long int.
Or, if either operand is a double,
the other operand is promoted to double.
This means that conversions such as that from a char
to a double
are perfectly valid. Once a conversion has
been applied, each pair of operands will be of the same type, and the
result of each operation will be the same as the type of both
operands. For example, consider the type conversions that occur in
Figure 3-1. First, the character ch
is promoted to int.
Then the outcome of ch/i
is converted to a double
because f*d
is a double.
The final result is double
because, by this time, both operands are
double.
Converting to and from bool
As mentioned earlier, values of type bool
are automatically converted into the integers
0 or 1 when used in an integer expression. When an integer result is
converted to type bool,
0 becomes false and
a non-zero value becomes true.
Although bool is
a fairly
recent addition to C++, the automatic conversions to and
from integers mean that it has virtually no impact on older code.
Furthermore, the automatic conversions allow C++ to maintain its
original definition of true and false as zero and non-zero. Thus,
bool is
mostly a convenience to the programmer.
Casts
It is possible to force an expression to be of a
specific type by using a construct called a cast.
C++ defines five types of casts. Four allow
detailed and sophisticated control over casting, and are described
later in this book after objects have been explained. However, there
is one type of cast that you can use now. It is C++’s most general
cast because it can be used to transform any type into any other
type. It was also the only type of cast that early versions of C++
supported. The general form of this cast is (type)
expression
where type is
the target type into which you want to convert the expression. For
example,\ if you want to make sure the expression x/2
is evaluated to type float,
you can write (float) x /
2 Casts are often considered operators. As an
operator, a cast is unary and has the same precedence as any other
unary operator. There are times when a
cast can be very useful. For example, you may want to use an integer
for loop control, but also perform a computation on it that requires
a fractional part, as in the program shown here:
#include
<iostream>
using
namespace std;
int
main() // print i and i/2 with fractions
{
int
i;
for(i=1;
i<=100; ++i )
cout
<< i << "/ 2 is: " << (float) i / 2 <<
'\n';
return
0;
}
Without the cast (float)
in this
example, only an integer division would be performed. The cast
ensures that the fractional part of the answer will be displayed on
the screen.
Spacing and Parentheses
An expression in C++ may have tabs and spaces in it to
make it more readable. For example, the following two expressions are
the same, but the second is easier to read:
x=10/y*(127/x);
x = 10 / y * (127/x);
Use of redundant or additional parentheses will not
cause errors or slow down them execution of the expression. You are
encouraged to use parentheses to make clear the exact order of
evaluation, both for yourself and for others who may have to figure
out your program later. For example, which of the following two
expressions is easier to read?
x = y/3-34*temp+127;
x = (y/3) - (34*temp) + 127;
No comments:
Post a Comment