Exercise 3
EXPRESSIONS
Please note that the material on this website is not intended to be exhaustive. This is intended as a summary and supplementary material.
INTRODUCTION
An expression in C++ is a part of a statement that evaluates to: true, false, or some numeric value. Expressions are the basic building blocks of more sophisticated programming code.
Expressions are built out of operands and operators. Operands may be either variables or constants. Operators are typically used to perform calculations. For instance, if the integer variable count is equal to 1: the expression count + 1 evaluates to 2.
ARITHMETIC OPERATORS
In C++ all of the basic arithmetic operators are available. Two of these operators are unary, that is, they apply only to one variable or constant; the remainder are binary, that is, they apply to two variables or constants. Operators, of course, can have three or more variables and constants, but we will concentrate on the simplest operators first.
ARITHMETIC OPERATORS
OPERATOR DESCRIPTION USAGE
+ Unary plus This is rarely used, as, by convention, the + is understood: +count
– Unary minus This operator reverses the sign of a variable or constant: – count
+ Binary addition Used to add two operands: count1 + count2
– Binarysubtraction Used to subtract two operands: count1 – count2
* Binarymultiplication Used to multiply two operands: count1 * count2
/ Binary division Used to divide two operandst>: count1 / count2
% Binary modulus* Used to compute the remainder of the divison of two integers:count1 % count2
* Both operands must be integral values.
C++ considers the assignment symbol, =, to also be an operator, and it can be used with the other arithmetic operators in a kind of shorthand. When you combine an arithmetic operator with assignment,
you get a C++ statement, which has to be terminated by a semicolon.
THE ASSIGNMENT OPERATOR WITH ARITHMETIC OPERATORS
OPERATOR DESCRIPTION USAGE
= The assignmentoperator Used to set the value of one variable or constant to a variable or constant: count = 1;
+= Addition withassignment Used to add a quantity to a variable: count += 15;
–= Subtraction withassignment Used to subtract a quantity from a variable: count –= 4;
*= Multiplication withassignment Used to multiply a variable by a quantity: count *= 3.14;
/= Division withassignment Used to divide a variable by a quantity: count /= 2;
%= Modulus withassignment* Used to set a variable to the remainder when divided by a quantity: count %= 2;
*Both the variable and the quantity must be integral types.
The combination of arithmetic operators with assignment is considered a shorthand expression, as it combines two operations. Hence, the following two statements have exactly the same effect:
EXAMPLE: count = count + 1; count += 1;
The remaining arithmetic operators are the increment and decrement operators, and should only be used with care. These operators also combine an arithmetic operation with an assignment.
INCREMENT AND DECREMENT OPERATORS
OPERATOR USAGE
++<variable> Prefix form: increments the value of a variable before it is used for some otherpurpose: count1 = ++count2;
<variable>++ Postfix form: increments the value of a variable after it is used: count1 = count2++;
– – <variable>
Prefix form: decrements the value of the variable before it is used for some other purpose
<variable>– – Postfix form: decrements the value of a variable after it is used
Unfortunately, misuse of these last operators is common. For example, if count1 = 0, and count 2 = 1,
then always bear in mind the following:
EXAMPLE: count1 = ++count2; // first increments count2 to 2, // then sets count1 equal to 2
count1 = count2++; // first sets count1 equal to count2, or 1 // then increments count2 to 2
STRING AND CHARACTER OPERATORS
Some of the arithmetic operators are meaningful when applied to strings and characters. For instance, the assignment operator, =, makes sense when applied to strings and characters.
EXAMPLE: string str1, str2; str2 = "Hello World!"; str1 = str2;
char ch1, ch2; ch2 = 'A'; ch1 = ch2;
In addition, C++ has a very useful concatenation operator that makes sense when applied to strings and characters: the operator +.
EXAMPLE: string first = "John "; string mmiddle = "Fitzgerald "; string last = "Kennedy"; string str = first + middle + last; // yields the string: "John Fitzgerald Kennedy"
char ch1 = '\r'; char ch2 = '\n'; string str = ch1 + ch2; // yields the string: "\r\n"
NUMERIC, CHARACTER, AND STRING COMPARISONS
Comparisons are expressions that evaluate not to numbers but to one of the Boolean values: true, false. For instance, we can use the > symbol to evaluate whether: number1 > number2.
Comparisons can be true or false as long as both sides of the comparison are the same type. Generally, the compiler will enforce this rule, and not allow comparisons between quantities of different types; there are, however, a lot of exceptions.
Comparisons are not statements (they are parts of statements) and are not usually terminated by a semicolon (there are exceptions explained in other modules).
COMPARISONS BETWEEN NUMERIC, STRING, AND CHARACTER QUANTITIES
COMPARISON MEANING USAGE
== Equals string1 == string2
!= Not equal number1 != number2
> Greater than char1 > char2
>= Greater than or equal to string1 >= string2
< Less than number1 < number2
<= Less than or equal to char <= char2
Strings and characters are valid in comparisons because all characters are represented by integers (shown in the ASCII table); so for instance, the following is true: '0' < 'A'.
Be very careful to distinguish between the assignment operator, =, and the comparison operator, ==. One of the most common mistakes beginners make is using = when == is required (or vice versa).
COMPLEX EXPRESSIONS
Complex numeric expressions are built up with the arithmetic operators and parentheses, ( and ), to create more complex expressions. The parentheses are used to make sure the operators are applied in the correct order. Thus the following two expressions do NOT evaluate to the same number:
EXAMPLE: int num1 = 3; int num2 = 4; int num3 = 5; int num4, num5; num4 = (num1 * num2) + num3; num5 = num1 * (num2 + num3);
// equals 12 + 3, or 15 // equals 3 * 9, or 27
You probably remember from Algebra classes that the parentheses are not always necessary, and how to do this is discussed below under rules of precedence (below).
Complex comparisons are built up from operators, parentheses, and logical operators: AND (conjunction), OR (disjunction), and NOT (negation). True and false are Boolean truth values, and C++ supports variables and constants of the type bool. (Note: when you display Boolean variables or constants using cout, you will get '1' instead of 'T' or true, and '0' instead of 'F' or false.)
LOGICAL OPERATORS
OPERATOR MEANING USAGE NAME
&& AND (num1 == num2) && (num1 >= 0) Conjunction
|| OR (string1 < string2) || (string1 > string3) Disjunction
! NOT !boolean1 Negation
Logical operators produce complex comparisons, and they still must evaluate to true or false. The computer uses the following truth tables to evaluate complex comparisons.
A conjunction is ONLY TRUE when both parts (conjuncts) are true; otherwise, a conjunction is false.
E1 E2 E1 && E2
T T T
T F F
F T F
F F F
A disjunction is ONLY FALSE when both parts (disjuncts) are false; otherwise it is true.
E1 E2 E1 || E2
T T T
T F T
F T T
F F F
A negation has the opposite truth value.
E1 !E1
T F
F T
Using the truth tables you can determine the truth value of a complex comparison if you know the truth values of the component parts; for example, given:
EXAMPLE: bool condition1 = true; bool condition2 = false; bool condition3 = true; bool result;
result = condition1 && condition2; result = condition1 || condition2; result = !condition1; result = (condition1 || condition2) && condition3;
// is false // is true // is false // is true
BIT MANIPULATIONS
There are several operators that work on string of bits, which of course are just 0s and 1s. The truth tables for bitwise operators are just like their counterparts, the logical operators, except true is 1, and false is 0. The symbols used are: &, |, and ~, for AND, OR, and NOT, respectively. Warning: the symbols for bit manipulations are very similar to the logical operators (above); be very careful when using either to get the correct one.
Performing these operations involves comparing the binary representations of two integral types; for simplicity, we will consider only 8-bit quantities.
EXAMPLE: 01010010 & 11001010, yields 01000010
01010010 | 11001010, yields 11011010
~11001010, yields 00110101, also called the one's complement of 11001010
C++ also supports bit shift operators: << and >>, left shift and right shift, respectively. When shift operations are used 0s are shifted into the quantity to replace the bits that were there. These are rarely used, but come in mighty handy when you want the separate parts of a longer binary representation. For instance, 32-bit Internet addresses are displayed using dot notation: 192.168.1.13, but in binary this address is: 11000001 10100100 00000001 00001101.
If we shift the 32-bit binary representation right by 24 bits (>> 24), we get:
11000001 10100100 00000001 00001101 >> 24 = 00000000 00000000 00000000 11000001, or 192
PRECEDENCE AND PARENTHESES
The precedence rules allow you to often dispense with a whole lot of parentheses. Complex expressions with a lot of parentheses are simply harder to read. For instance, when evaluating num1 * num2 - num3 / num4 + num5, the rules say:
evaluate the *s and /s first, from left to right, then evaluate the +s and -s next, from left to right.
So our example (with parentheses) evaluates to:
(num1 * num2) - (num3 / num4) + num5.
If you want the expression evaluated so the +s and -s are done first, then you have to use:
num1 * (num2 - num3) / (num4 + num5).
The rules of precedence are listed in Operator Precedence.
DATA TYPE CONVERSIONS
When you have expressions that have numeric quantities of different types, the result will, in some cases, be automatically converted to one type or the other; you need to be aware of how this works.
For instance, if you divide a float quantity by an int quantity and store the result in a float quantity, the compiler will first convert the int quantity to a float (automatically) before performing the division. That is, the int quantity is first converted to the "more accurate" type: float.
EXAMPLE: int num1 = 32; float num2 = 3.2; float num3 = num2 / num1; // yields num3 = 0.1
However, if you perform the same division, and store the result in an int quantity, you will get a significantly different result. The int quantity (num1) still gets converted to float (the "more accurate" type), and the division is performed (and again gets 0.1). But, because the result is going into an int, the decimal part of the result of the division will be truncated.
EXAMPLE: int num3 = num2 / num1 // yields num3 = 0
Truncation will also occur when you try the following.
EXAMPLE: short num1; int num2 = 70000; num1 = num2; // num1 will = 4464
The largest quantity that can be stored in a short is 16 bits, and 70000 is too large to be stored in just 16 bits. Hence, the result will have the upper two bytes of the 32-bit int (num2) truncated, and you will get 70,000 - 65536 = 4464. The 4464 is the only part of the int (num2) that "fits" in 16 bits. Something similar happens when you try to store a very small (decimal) number is a type that cannot be that small.
C++ provides a mechanism, called casting that allows you to force quantities to be converted either before or after arithmetic operations are performed. There are two ways to perform casts. Consider:
EXAMPLE: int num1 = 32; float num2 = 3.2; float num3 = (int) num2 / num1; float num4 = int (num2) / num1;
// yields num3 = 0.09375 // yields num4 = 0.09375
In this case num2 is converted to an int before the division is performed: 3.2 gets truncated to 3. Then, 3 is divided by 32, i.e., 3 / 32, and is stored as a float.
As division by 0 is not defined in arithmetic, the question arises: what will happen if your program does attempt to divide by 0? In C++ nothing will happen until your running program attempts to divide by 0; then the attempt will result in a runtime error: Your program will be aborted by the OS before it can run
to completion. In C++ you will get the runtime error: "floating point exception."
Review Exercises
1. What are the results (num3, num4, …, num10) of the following code snippet?
int num1 = 2; int num2 = 4; int num3 = -(num2 / num1); int num4 = -num1 / num2; int num5 = num1 / -num2; int num6 = num1 + num2 / num1; int num7 = (num1 + num2) / num1; int num8 = num1 + (num2 / num1); int num9 = num1 / num2; int num10 = num2 % num1;
2. What are the results (string4, string5, and string6) of the following code snippet?
string string1 = "Mary"; string string2 = "Tyler"; string string3 = "Moore"; string string4 = string1 + ' ' + string2 + ' ' + string3; string string5 = string3 + ", " + string1 + ' ' + string2; string string6 = string1 + '\n' + string2 + '\n' + string3 + '\n';
3. What are the results (result1, result2, result3, and result4) of the following code snippet?
int num1 = 2; int num2 = 4; int num3 = 0; bool result1 = num1 < num2; bool result2 = !(num1 > num2); bool result3 = -num2 < num3; bool result4 = (num1 < num2) && (num3 < num1);
© 2011 cad rcm cpsm