![]() |
Essentials of C++: Section II |
|
Declarations are statements. They state something to the compiler. Almost every bit of code we write in C++ is a statement. Here we focus on statements that use operators. When you want to assign a value to some variable, you write an assignment statement. The simplest assignment statements use the assignment operator (=) to assign the value of one variable or constant to a variable:
More complex assignment statements can be formed through the use of additional operators. Such statements are called expressions. An expression uses some set of operators and lvalues that together form an instruction for a computer to perform. The two statements above are examples of simple expressions. In what follows we discuss a subset of the C++ operators. All of these
return a value although that value is often not important in the use of
the operator. A. Binary Arithmetic Operators and the Assignment Statement
These can be combined in any number of ways and used with the
assignment operator (=) to make complex arithmetic expressions such
as: There are also a number of operators that combine assignment with some
other arithmetic operator:
is another way of writing: B. Unary Arithmetic Operators For example: The other two most commonly used unary arithmetic operators are: These can be used both as prefix and postfix operators meaning that the '++' or '--' can be placed before or after the lvalue and the results of the computation will be different. When placed before an lvalue as in: the lvalue is modified first and then its value is returned. When placed after an lvalue as in: the value is returned before it is incremented. C. Relational Operators
These can be used to create expressions such as which cause a computer to compare the value of the two variables and
return true (some value other than 0) or false (the value 0). They can
also be used with the assignment operator as in: This causes the system to compare 'value1' with 'value2' and store true
or false in 'value3'. See the iteration
and selection statements below for
examples using these operators. D. Logical Operators
The first two are binary operators and require two expressions. The '&&' operator returns a non-zero value (true) if both expressions are true, otherwise it returns false. The '||' operator returns a non-zero value if one or both of the expressions is true. The last one is a unary operator that returns true if the expression associated with it is false and vs versa. Most often these operators are used with relational expressions as in: Description in "The Story of C++" E. Other Operators
These operators are only vaguely described above and in some cases they
have broader application than mentioned. Where provided, you should follow
the links to the relevant sections for more information. F. Operator Precedence Most programming languages give a higher priority (precedence) to multiplication (*) and thus in this example the operation 'value1 * value2' will be performed before 'value3' is subtracted. If one wants the operation 'value2 - value3' performed first, one must use parentheses as in: A more complex example involves the logical operators. Assume that 'E1', 'E2', and 'E3' below are expressions that return true or false. The result of the following expression, then, depends not only on the truth values of 'E1', 'E2' and 'E3' but on the order in which the '&&' and '||' (AND and OR) operations are performed: The specifications for a programming language must indicate the order of precedence for all operators in the language to ensure that all implementations of the language produce the same results. In C++ the precedence for the operators listed above is as follows (from highest to lowest):
This tells us that in the logical expression above, the operation 'E1 && E2' will be performed first. If one wants the '||' operation performed first, parentheses should be used as in: Most operators assume that their operands are of the same type. Thus,
it is not possible to add an integer and a string - what would be the
meaning of such an operation? However, if this rule of 'sameness' were
enforced too strictly, it would make C++ an awkward language. For example,
it makes sense to add an integer to a long or to a double. To handle this
C++ allows what are called implicit conversions (also called
type coercions) of one operand to the type of a second operand -
when the conversion is appropriate. In the example involving the addition
of an int and a long, the integer would be converted to a long. In the
example involving an int and a double, the integer would be converted to a
double. Such conversions are called 'implicit' conversions because they
take place automatically. C++ provides a set of conversion rules (also called 'promotion' rules) that guide the type of implicit conversions that take place. These rules are based on the principle of "no surprises". This refers to the idea that a programming language should be designed to provide warnings or somehow make it more difficult for programmers to write code that results in 'strange' answers. In other words, implicit type conversions should only be allowed when the results are not likely to produce unexpected results. As an example of an 'unexpected' result: one could, in principle, allow values of type double to be implicitly converted to integers. The most likely way to do this would be to drop the information to the right of the decimal point. However, if this is allowed and a programmer forgets what this means, he or she is likely to be surprised with the calculations produced by a program using such conversions. The built-in types of C++ are arranged in order from 'lower' to 'higher' types, where a value of a lower type can be implicitly converted to a value of a higher type. 'Higher' here essentially means that the type can hold all the information contained in a 'lower' type and no information is lost in a conversion. Thus, C++ will implicitly convert an int to a double but not a double to an int. In the latter case, information is lost when the 'data' to the right of the decimal point is truncated. Here is that part of the conversion hierarchy listing the types described above in Section I:
The precise rules for implicit conversions can be found in C++ manuals. C++ does allow programmers to make their own explicit conversions. This allows the programmer who is willing to accept the risk, to do whatever he or she wishes. First, one can explicitly assign a value of a higher type to a variable of a lower type as in:
or
In both these cases the answer will be truncated when it is stored in the variable 'x'. Similarly, one can use a value of a higher type as the actual argument in a call to a function with a corresponding formal argument of a lower type. This is seen as a type of assignment. Finally, one can type cast values from one type to another. To do this, one writes the name of the type to be converted to, followed by a set of parentheses surrounding the variable or expression to be converted. For example, explicitly converts the variable 'w' into an integer before adding it
to 'x'. Links to 'The Story of C++" and other documents
|