Chapter 5. Expressions


CONTENTS

Section 5.1 Arithmetic Operators

149

Section 5.2 Relational and Logical Operators

152

Section 5.3 The Bitwise Operators

154

Section 5.4 Assignment Operators

159

Section 5.5 Increment and Decrement Operators

162

Section 5.6 The Arrow Operator

164

Section 5.7 The Conditional Operator

165

Section 5.8 The sizeof Operator

167

Section 5.9 Comma Operator

168

Section 5.10 Evaluating Compound Expressions

168

Section 5.11 The new and delete Expressions

174

Section 5.12 Type Conversions

178

Chapter Summary

188

Defined Terms

188


C++ provides a rich set of operators and defines what these operators do when applied to operands of built-in type. It also allows us to define meanings for the operators when applied to class types. This facility, known as operator overloading, is used by the library to define the operators that apply to the library types.

In this chapter our focus is on the operators as defined in the language and applied to operands of built-in type. We will also look at some of the operators defined by the library. Chapter 14 shows how we can define our own overloaded operators.

An expression is composed of one or more operands that are combined by operators. The simplest form of an expression consists of a single literal constant or variable. More complicated expressions are formed from an operator and one or more operands.

Every expression yields a result. In the case of an expression with no operator, the result is the operand itself, e.g., a literal constant or a variable. When an object is used in a context that requires a value, then the object is evaluated by fetching the object's value. For example, assuming ival is an int object,

      if (ival)            // evaluate ival as a condition          // .... 

we could use ival as an expression in the condition of an if. The condition succeeds if the value of ival is not zero and fails otherwise.

The result of expressions that involve operators is determined by applying each operator to its operand(s). Except when noted otherwise, the result of an expression is an rvalue (Section 2.3.1, p. 45). We can read the result but cannot assign to it.

The meaning of an operatorwhat operation is performed and the type of the resultdepends on the types of its operands.



Until one knows the type of the operand(s), it is not possible to know what a particular expression means. The expression

      i + j 

might mean integer addition, concatenation of strings, floating-point addition, or something else entirely. How the expression is evaluated depends on the types of i and j.

There are both unary operators and binary operators. Unary operators, such as address-of (&) and dereference (*), act on one operand. Binary operators, such as addition (+) and subtraction (-), act on two operands. There is also one ternary operator that takes three operands. We'll look at this operator in Section 5.7 (p. 165).

Some symbols, such as *, are used to represent both a unary and a binary operator. The * symbol is used as the (unary) dereference operator and as the (binary) multiplication operator. The uses of the symbol are independent; it can be helpful to think of them as two different symbols. The context in which an operator symbol is used always determines whether the symbol represents a unary or binary operator.

Operators impose requirements on the type(s) of their operand(s). The language defines the type requirements for the operators when applied to built-in or compound types. For example, the dereference operator, when applied to an object of built-in type, requires that its operand be a pointer type. Attempting to dereference an object of any other built-in or compound type is an error.

The binary operators, when applied to operands of built-in or compound type, usually require that the operands be the same type, or types that can be converted to a common type. We'll look at conversions in Section 5.12 (p. 178). Although the rules can be complex, for the most part conversions happen in expected ways. For example, we can convert an integer to floating-point, and vice versa, but we cannot convert a pointer type to floating-point.

Understanding expressions with multiple operators requires understanding operator precedence, associativity, and the order of evaluation of the operands. For example, the expression

      5 + 10 * 20/2; 

uses addition, multiplication, and division. The result of this expression depends on how the operands are grouped to the operators. For example, the operands to the * operator could be 10 and 20, or 10 and 20/2, or 15 and 20 or 15 and 20/2. Associativity and precedence rules specify the grouping of operators and their operands. In C++ this expression evaluates to 105, which is the result of multiplying 10 and 20, dividing that result by 2, and then adding 5.

Knowing how operands and operators are grouped is not always sufficient to determine the result. It may also be necessary to know in what order the operands to each operator are evaluated. Each operator controls what assumptions, if any, can be made as to the order in which the operands will be evaluatedthat is, whether we can assume that the left-hand operand is always evaluated before the right or not. Most operators do not guarantee a particular order of evaluation. We will cover these topics in Section 5.10 (p. 168).



C++ Primer
C Primer Plus (5th Edition)
ISBN: 0672326965
EAN: 2147483647
Year: 2006
Pages: 223
Authors: Stephen Prata

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net