0% found this document useful (0 votes)
29 views13 pages

Chap 02

Uploaded by

pamusulacikala
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
29 views13 pages

Chap 02

Uploaded by

pamusulacikala
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 13

2.

Expressions

This chapter introduces the built-in C++ operators for composing expressions.
An expression is any computation which yields a value.
When discussing expressions, we often use the term evaluation. For
example, we say that an expression evaluates to a certain value. Usually the
final value is the only reason for evaluating the expression. However, in some
cases, the expression may also produce side-effects. These are permanent
changes in the program state. In this sense, C++ expressions are different from
mathematical expressions.
C++ provides operators for composing arithmetic, relational, logical,
bitwise, and conditional expressions. It also provides operators which produce
useful side-effects, such as assignment, increment, and decrement. We will
look at each category of operators in turn. We will also discuss the precedence
rules which govern the order of operator evaluation in a multi-operator
expression.

www.pragsoft.com Chapter 2: Expressions 17


Arithmetic Operators

C++ provides five basic arithmetic operators. These are summarized in Table
2.1.

Table 2.1 Arithmetic operators.


Operator Name Example
+ Addition 12 + 4.9 // gives 16.9
- Subtraction 3.98 - 4 // gives -0.02
* Multiplication 2 * 3.4 // gives 6.8
/ Division 9 / 2.0 // gives 4.5
% Remainder 13 % 3 // gives 1

Except for remainder (%) all other arithmetic operators can accept a mix
of integer and real operands. Generally, if both operands are integers then the
result will be an integer. However, if one or both of the operands are reals
then the result will be a real (or double to be exact).
When both operands of the division operator (/) are integers then the
division is performed as an integer division and not the normal division we
are used to. Integer division always results in an integer outcome (i.e., the
result is always rounded down). For example:
9 / 2 // gives 4, not 4.5!
-9 / 2 // gives -5, not -4!

Unintended integer divisions are a common source of programming


errors. To obtain a real division when both operands are integers, you should
cast one of the operands to be real:
int cost = 100;
int volume = 80;
double unitPrice = cost / (double) volume; // gives 1.25

The remainder operator (%) expects integers for both of its operands. It
returns the remainder of integer-dividing the operands. For example 13%3 is
calculated by integer dividing 13 by 3 to give an outcome of 4 and a remainder
of 1; the result is therefore 1.
It is possible for the outcome of an arithmetic operation to be too large
for storing in a designated variable. This situation is called an overflow. The
outcome of an overflow is machine-dependent and therefore undefined. For
example:
unsigned char k = 10 * 92; // overflow: 920 > 255

It is illegal to divide a number by zero. This results in a run-time division-


by-zero failure which typically causes the program to terminate. 

18 C++ Programming Copyright © 1998 Pragmatix Software


Relational Operators

C++ provides six relational operators for comparing numeric quantities. These
are summarized in Table 2.2. Relational operators evaluate to 1 (representing
the true outcome) or 0 (representing the false outcome).

Table 2.2 Relational operators.


Operator Name Example
== Equality 5 == 5 // gives 1
!= Inequality 5 != 5 // gives 0
< Less Than 5 < 5.5 // gives 1
<= Less Than or Equal 5 <= 5 // gives 1
> Greater Than 5 > 5.5 // gives 0
>= Greater Than or Equal 6.3 >= 5 // gives 1

Note that the <= and >= operators are only supported in the form shown.
In particular, =< and => are both invalid and do not mean anything.
The operands of a relational operator must evaluate to a number.
Characters are valid operands since they are represented by numeric values.
For example (assuming ASCII coding):
'A' < 'F' // gives 1 (is like 65 < 70)

The relational operators should not be used for comparing strings,


because this will result in the string addresses being compared, not the string
contents. For example, the expression
"HELLO" < "BYE"

causes the address of "HELLO" to be compared to the address of "BYE". As


these addresses are determined by the compiler (in a machine-dependent
manner), the outcome may be 0 or may be 1, and is therefore undefined.
C++ provides library functions (e.g., strcmp) for the lexicographic
comparison of string. These will be described later in the book.

www.pragsoft.com Chapter 2: Expressions 19


Logical Operators

C++ provides three logical operators for combining logical expression. These
are summarized in Table 2.3. Like the relational operators, logical operators
evaluate to 1 or 0.

Table 2.3 Logical operators.


Operator Name Example
! Logical Negation !(5 == 5) // gives 0
&& Logical And 5 < 6 && 6 < 6 // gives 1
|| Logical Or 5 < 6 || 6 < 5 // gives 1

Logical negation is a unary operator, which negates the logical value of


its single operand. If its operand is nonzero it produce 0, and if it is 0 it
produces 1.
Logical and produces 0 if one or both of its operands evaluate to 0.
Otherwise, it produces 1. Logical or produces 0 if both of its operands
evaluate to 0. Otherwise, it produces 1.
Note that here we talk of zero and nonzero operands (not zero and 1). In
general, any nonzero value can be used to represent the logical true, whereas
only zero represents the logical false. The following are, therefore, all valid
logical expressions:
!20 // gives 0
10 && 5 // gives 1
10 || 5.5 // gives 1
10 && 0 // gives 0

C++ does not have a built-in boolean type. It is customary to use the type
int for this purpose instead. For example:

int sorted = 0; // false


int balanced = 1; // true

20 C++ Programming Copyright © 1998 Pragmatix Software


Bitwise Operators

C++ provides six bitwise operators for manipulating the individual bits in an
integer quantity. These are summarized in Table 2.4.

Table 2.4 Bitwise operators.


Operator Name Example
~ Bitwise Negation ~'\011' // gives '\366'
& Bitwise And '\011' & '\027' // gives '\001'
| Bitwise Or '\011' | '\027' // gives '\037'
^ Bitwise Exclusive Or '\011' ^ '\027' // gives '\036'
<< Bitwise Left Shift '\011' << 2 // gives '\044'
>> Bitwise Right Shift '\011' >> 2 // gives '\002'

Bitwise operators expect their operands to be integer quantities and treat


them as bit sequences. Bitwise negation is a unary operator which reverses the
bits in its operands. Bitwise and compares the corresponding bits of its
operands and produces a 1 when both bits are 1, and 0 otherwise. Bitwise or
compares the corresponding bits of its operands and produces a 0 when both
bits are 0, and 1 otherwise. Bitwise exclusive or compares the corresponding
bits of its operands and produces a 0 when both bits are 1 or both bits are 0,
and 1 otherwise.
Bitwise left shift operator and bitwise right shift operator both take a bit
sequence as their left operand and a positive integer quantity n as their right
operand. The former produces a bit sequence equal to the left operand but
which has been shifted n bit positions to the left. The latter produces a bit
sequence equal to the left operand but which has been shifted n bit positions to
the right. Vacated bits at either end are set to 0.
Table 2.5 illustrates bit sequences for the sample operands and results in
Table 2.4. To avoid worrying about the sign bit (which is machine dependent),
it is common to declare a bit sequence as an unsigned quantity:
unsigned char x = '\011';
unsigned char y = '\027';

Table 2.5 How the bits are calculated.


Example Octal Value Bit Sequence
x 011 0 0 0 0 1 0 0 1
y 027 0 0 0 1 0 1 1 1
~x 366 1 1 1 1 0 1 1 0
x & y 001 0 0 0 0 0 0 0 1
x | y 037 0 0 0 1 1 1 1 1
x ^ y 036 0 0 0 1 1 1 1 0
x << 2 044 0 0 1 0 0 1 0 0
x >> 2 002 0 0 0 0 0 0 1 0

www.pragsoft.com Chapter 2: Expressions 21


Increment/Decrement Operators

The auto increment (++) and auto decrement (--) operators provide a
convenient way of, respectively, adding and subtracting 1 from a numeric
variable. These are summarized in Table 2.6. The examples assume the
following variable definition:
int k = 5;

Table 2.6 Increment and decrement operators.


Operator Name Example
++ Auto Increment (prefix) ++k + 10 // gives 16
++ Auto Increment (postfix) k++ + 10 // gives 15
-- Auto Decrement (prefix) --k + 10 // gives 14
-- Auto Decrement (postfix) k-- + 10 // gives 15

Both operators can be used in prefix and postfix form. The difference is
significant. When used in prefix form, the operator is first applied and the
outcome is then used in the expression. When used in the postfix form, the
expression is evaluated first and then the operator applied.
Both operators may be applied to integer as well as real variables,
although in practice real variables are rarely useful in this form.

22 C++ Programming Copyright © 1998 Pragmatix Software


Assignment Operator

The assignment operator is used for storing a value at some memory location
(typically denoted by a variable). Its left operand should be an lvalue, and its
right operand may be an arbitrary expression. The latter is evaluated and the
outcome is stored in the location denoted by the lvalue.
An lvalue (standing for left value) is anything that denotes a memory
location in which a value may be stored. The only kind of lvalue we have seen
so far in this book is a variable. Other kinds of lvalues (based on pointers and
references) will be described later in this book.
The assignment operator has a number of variants, obtained by combining
it with the arithmetic and bitwise operators. These are summarized in Table
2.7. The examples assume that n is an integer variable.

Table 2.7 Assignment operators.


Operator Example Equivalent To
= n = 25
+= n += 25 n = n + 25
-= n -= 25 n = n - 25
*= n *= 25 n = n * 25
/= n /= 25 n = n / 25
%= n %= 25 n = n % 25
&= n &= 0xF2F2 n = n & 0xF2F2
|= n |= 0xF2F2 n = n | 0xF2F2
^= n ^= 0xF2F2 n = n ^ 0xF2F2
<<= n <<= 4 n = n << 4
>>= n >>= 4 n = n >> 4

An assignment operation is itself an expression whose value is the value


stored in its left operand. An assignment operation can therefore be used as
the right operand of another assignment operation. Any number of
assignments can be concatenated in this fashion to form one expression. For
example:
int m, n, p;
m = n = p = 100; // means: n = (m = (p = 100));
m = (n = p = 100) + 2; // means: m = (n = (p = 100)) + 2;

This is equally applicable to other forms of assignment. For example:


m = 100;
m += n = p = 10; // means: m = m + (n = p = 10);

www.pragsoft.com Chapter 2: Expressions 23


Conditional Operator

The conditional operator takes three operands. It has the general form:

operand1 ? operand2 : operand3

First operand1 is evaluated, which is treated as a logical condition. If the


result is nonzero then operand2 is evaluated and its value is the final result.
Otherwise, operand3 is evaluated and its value is the final result. For example:
int m = 1, n = 2;
int min = (m < n ? m : n); // min receives 1

Note that of the second and the third operands of the conditional operator
only one is evaluated. This may be significant when one or both contain side-
effects (i.e., their evaluation causes a change to the value of a variable). For
example, in
int min = (m < n ? m++ : n++);

m is incremented because m++ is evaluated but n is not incremented because


n++ is not evaluated.
Because a conditional operation is itself an expression, it may be used as
an operand of another conditional operation, that is, conditional expressions
may be nested. For example:
int m = 1, n = 2, p =3;
int min = (m < n ? (m < p ? m : p)
: (n < p ? n : p));

24 C++ Programming Copyright © 1998 Pragmatix Software


Comma Operator

Multiple expressions can be combined into one expression using the comma
operator. The comma operator takes two operands. It first evaluates the left
operand and then the right operand, and returns the value of the latter as the
final outcome. For example:
int m, n, min;
int mCount = 0, nCount = 0;
//...
min = (m < n ? mCount++, m : nCount++, n);

Here when m is less than n, mCount++ is evaluated and the value of m is stored
in min. Otherwise, nCount++ is evaluated and the value of n is stored in min.

www.pragsoft.com Chapter 2: Expressions 25


The sizeof Operator

C++ provides a useful operator, sizeof, for calculating the size of any data
item or type. It takes a single operand which may be a type name (e.g., int) or
an expression (e.g., 100) and returns the size of the specified entity in bytes.
The outcome is totally machine-dependent. Listing 2.1 illustrates the use of
sizeof on the built-in types we have encountered so far.

Listing 2.1
1 #include <iostream.h>

2 int main (void)


3 {
4 cout << "char size = " << sizeof(char) << " bytes\n";
5 cout << "char* size = " << sizeof(char*) << " bytes\n";
6 cout << "short size = " << sizeof(short) << " bytes\n";
7 cout << "int size = " << sizeof(int) << " bytes\n";
8 cout << "long size = " << sizeof(long) << " bytes\n";
9 cout << "float size = " << sizeof(float) << " bytes\n";
10 cout << "double size = " << sizeof(double) << " bytes\n";

11 cout << "1.55 size = " << sizeof(1.55) << " bytes\n";
12 cout << "1.55L size = " << sizeof(1.55L) << " bytes\n";
13 cout << "HELLO size = " << sizeof("HELLO") << " bytes\n";
14 }

When run, the program will produce the following output (on the author’s
PC):
char size = 1 bytes
char* size = 2 bytes
short size = 2 bytes
int size = 2 bytes
long size = 4 bytes
float size = 4 bytes
double size = 8 bytes
1.55 size = 8 bytes
1.55L size = 10 bytes
HELLO size = 6 bytes

26 C++ Programming Copyright © 1998 Pragmatix Software


Operator Precedence

The order in which operators are evaluated in an expression is significant and


is determined by precedence rules. These rules divide the C++ operators into a
number of precedence levels (see Table 2.8). Operators in higher levels take
precedence over operators in lower levels.

Table 2.8 Operator precedence levels.


Level Operator Kind Order
Highest :: Unary Both
() [] -> . Binary Left to Right
+ ++ ! * new sizeof
Unary Right to Left
- -- ~ & delete ()
->* .* Binary Left to Right
* / % Binary Left to Right
+ - Binary Left to Right
<< >> Binary Left to Right
< <= > >= Binary Left to Right
== != Binary Left to Right
& Binary Left to Right
^ Binary Left to Right
| Binary Left to Right
&& Binary Left to Right
|| Binary Left to Right
? : Ternary Left to Right
= += *= ^= &= <<=
Binary Right to Left
-= /= %= |= >>=
Lowest , Binary Left to Right

For example, in
a == b + c * d

c * d is evaluated first because * has a higher precedence than + and ==. The
result is then added to b because + has a higher precedence than ==, and then
== is evaluated. Precedence rules can be overridden using brackets. For
example, rewriting the above expression as
a == (b + c) * d

causes + to be evaluated before *.


Operators with the same precedence level are evaluated in the order
specified by the last column of Table 2.8. For example, in
a = b += c

the evaluation order is right to left, so first b += c is evaluated, followed by a


= b. 

www.pragsoft.com Chapter 2: Expressions 27


Simple Type Conversion

A value in any of the built-in types we have see so far can be converted (type-
cast) to any of the other types. For example:
(int) 3.14 // converts 3.14 to an int to give 3
(long) 3.14 // converts 3.14 to a long to give 3L
(double) 2 // converts 2 to a double to give 2.0
(char) 122 // converts 122 to a char whose code is 122
(unsigned short) 3.14 // gives 3 as an unsigned short

As shown by these examples, the built-in type identifiers can be used as


type operators. Type operators are unary (i.e., take one operand) and appear
inside brackets to the left of their operand. This is called explicit type
conversion. When the type name is just one word, an alternate notation may
be used in which the brackets appear around the operand:
int(3.14) // same as: (int) 3.14

In some cases, C++ also performs implicit type conversion. This


happens when values of different types are mixed in an expression. For
example:
double d = 1; // d receives 1.0
int i = 10.5; // i receives 10
i = i + d; // means: i = int(double(i) + d)

In the last example, i + d involves mismatching types, so i is first converted


to double (promoted) and then added to d. The result is a double which does
not match the type of i on the left side of the assignment, so it is converted to
int (demoted) before being assigned to i.
The above rules represent some simple but common cases for type
conversion. More complex cases will be examined later in the book after we
have discussed other data types and classes.

28 C++ Programming Copyright © 1998 Pragmatix Software


Exercises

2.1 Write expressions for the following:


 To test if a number n is even.
 To test if a character c is a digit.
 To test if a character c is a letter.
 To do the test: n is odd and positive or n is even and negative.
 To set the n-th bit of a long integer f to 1.
 To reset the n-th bit of a long integer f to 0.
 To give the absolute value of a number n.
 To give the number of characters in a null-terminated string literal s.

2.2 Add extra brackets to the following expressions to explicitly show the order in
which the operators are evaluated:
(n <= p + q && n >= p - q || n == 0)
(++n * q-- / ++p - q)
(n | p & q ^ p << 2 + q)
(p < q ? n < p ? q * n - 2 : q / n + 1 : q - n)

2.3 What will be the value of each of the following variables after its initialization:
double d = 2 * int(3.14);
long k = 3.14 - 3;
char c = 'a' + 2;
char c = 'p' + 'A' - 'a';

2.4 Write a program which inputs a positive integer n and outputs 2 raised to the
power of n.

2.5 Write a program which inputs three numbers and outputs the message Sorted
if the numbers are in ascending order, and outputs Not sorted otherwise.

www.pragsoft.com Chapter 2: Expressions 29

You might also like