1 Expressions and Assignment Statements Expressions are the fundamental means of specifying computations in a programming language. Arithmetic Expressions Primary issues to consider: 1. What are the arithmetic operators of the language? 2. What are the operator precedence rules? 3. What are the operator associativity rules? 4. What is the order of operand evaluation? 5. Are there restrictions on operand evaluation side effects? 6. Does the language allow user-defined operator overloading? 7. What mode mixing is allowed in expressions? Binary Arithmetic Operators in C/C++ Operation Operator Example Operand Result Addition + A+B Both integers ------------------One operand is not integer Integer -----------------Double precision floating-point Subtraction - A–B Both integers ---------------------------One operand is not integer Integer ----------------------Double precision floating-point Multiplication * A*B Both integers -----------------------------One operand is not integer Integer ------------------------Double precision floating-point Division / A/B Both integers -----------------------------One operand is not integer Integer ------------------------Double precision floating-point Modulus (Remainder) % A%B Both integers Integer 2 Evaluating Simple Arithmetic Expressions Arithmetic expression Result 12 + 9 21 18 - 13 5 14.78 + 3.51 18.29 12.50 * 4 50.00 15 / 2 7 15 % 2 1 15. / 2 7.50 8 / 3.0 2.666.... Unary Arithmetic Operators in C/C++ and Java Unary Plus ( +A ): Examples: +num, +num / 5, num1 * +num2 It has no effect on its operand in C/C++. In Java, it causes an implicit conversion of a char, short, or byte operand to int type; otherwise, it has no effect on its operand. Unary Minus ( - A ): Examples: The pre-increment Operator: -num, -num / 5, num1 * -num2 is specified as follows: ++<variable-name> It says to add 1 to the current value of the variable and then to use the new value (if necessary). The post-increment Operator: is specified as follows: <variable-name>++ It says to use the current value of the variable (if necessary) and then add 1 to it. The pre-decrement Operator: is specified as follows: - - <variable-name> It says to subtract 1 from the current value of the variable and then to use the new value (if necessary). The post-decrement Operator: is specified as follows: <variable-name> - - It says to use the current value of the variable (if necessary) and then subtract 1 from it. 3 Examples a) int num = 5; num++ ; // the value of variable num is not used // num = 6 b) int num = 5; ++num; // the value of variable num is not used // num = 6 c) int num1 = 5, num2 = 5, result1, result2; reult1 = ++num1 - 3; // add 1 to the value of num1, then use it // num1 = 6 and result1 = 3 result2 = num2++ - 3; // use the value of num2, then add 1 to it // num2 = 6 and result2 = 2 d) int num = 5; num - - ; // the value of variable num is not used // num = 4 e) int num = 5; - - num; // the value of variable num is not used // num = 4 f) int num1 = 5, num2 = 5, result1, result2; reult1 = - - num1 + 3; //subtract 1 from the value of num1, then use it result2 = num2 - - + 3; // use the value of num2, then subtract 1 from it //num1 = 4 result1 = 7 //num2 = 4 result2 = 8 Operator Evaluation Order Precedence: Highest in C++ and Java ++, - - (postfix and prefix) Unary +, *, / , % Lowest Binary + , - Associativity: in C++ and Java Left-to right: * , / , % , binary +, binary – Right-to left: ++ , - - , unary - , unary + Examples num1 + num2 – num3 + num4 ----> ( ( ( num1 + num2 ) – num3 ) + num4 ) - num1++ * num2 + - - num3 ----> ( ( ( - (num1++) ) * num2 ) + ( - - num3 ) ) - num1 % num2 * num3 - num4 / 6 ----> ( ( ( ( - num1) % num2 ) * num3 ) – (num4 /6 ) ) 4 Parentheses The precedence and the associativity rules can be altered by placing parentheses in expressions. A parenthesized part of an expression has precedence over its adjacent un-parenthesized parts. User-Defined Operator Overloading User-defined operator overloading is allowed in C++, but not in Java. Operand Evaluation Order Operand evaluation order refers to the order in which the values of the operands of an expression are fetched from the memory. For example, in the expression A+B Is the value variable A obtained before that of variable B or that of variable B is obtained before? This order is important if one of the operands of an expression has side effects. A functional side effect occurs when in a function call, the values of one or more arguments or global variables are changed. The order of operand evaluation is left-to-right in Java; it is not specified in C++. Avoid expressions with side effects in any language. Examples int global = 5; int funct1 ( ) { global ++; return 3; } int funct2 ( int & para) { Para ++; return 3; } 5 int main ( ) { int num1 = 5, result1, result2; result1 = global + funct1( ); result2 = num1 + funct2 ( num1 ); cout << “result1=\t” << result1 << “\t result2=\t” << result2; return 0; } If the operands are evaluated left-to right, the output will be: If they are evaluated right-to-left, the output will be: result1= 8 result2= 8 result1= 9 result2= 9 Type Conversions A mixed-mode expression is an expression in which one or more operators have operands with different data types. Example int num = 3; double result, dnum = 12.5; result = dnum / num; A language that allows mixed-mode expressions must provide a rule for implicit operand type conversions (or coercion) because computers do not have binary operations that take operands with different data types. A narrowing conversion converts a value to a type that cannot store even approximations of all of the values of the original type. For example, a double to int in C++. A widening conversion converts a value to a type that can include at least approximations of all the values of the original type. For example, an int to float in C++ and Java. An assignment conversion is an implicit conversion that occurs when the l-value (variable) and the value of the expression (r-value) in the assignment statement do not have the same data type. Examples char var; int num1, num2; double dnum1, dnum2; cin >> num1 >> dnum1; var = num1 /2; dnum2 = dnum1 / num1; // the integer result is converted to a character value // the integer value in the variable num1 is converted to // a double precision floating-point value 6 Explicit type conversions language. are specified by programmers by using operations provided by the In C-based languages, these operations are called casts: Examples: var = (char) (num1 /2); dnum2 = dnum1 / (double) num1; // the integer result is converted to a character value // the integer value in the variable num1 is converted to // a double precision floating-point value Logical Expressions A logical expression (or condition) is an expression that evaluates to either true or false. There are two types of conditions: simple conditions and Compound conditions. A simple condition has the following syntax: <arithmetic expression> <relational operator> <arithmetic expression> Relational Operators C/C++ Symbol Meaning < is less than > is greater than == is equal to <= is less than or equal to >= is greater than or equal to != is not equal to A compound condition is built from simple conditions and logical operators. Logical Operators C++ Symbol Meaning Evaluation AND <condition1> && <condition2> is true if and only if both conditions are true || OR <condition1> || <condition2> is true if and only if at least one of the two conditions is true ! NOT && !<condition> is true if and only if <condition> is false 7 Evaluations of compound conditions Assuming that the variables are defined and initialized as follows: int num1 = 5, num2 = 7, num3 = 2; float fnum = 11.75; char ch = ‘K’; Compute the true value of each of the following compound conditions: a) num1 >= 5 || num2 + 3 == num3 d) num2 + 3 == num3 * 4 || ch >= ‘Z’ b) ‘A’ <= ch && fnum + 7.2 != 2.5 e) num1 < 3 && num2 > num3 c) !(3 * num1 + 4 < num3 * 2) f) num1 + 4 > num3 || fnum > num1 + 20 && num3 < 5 Solutions d) num2 + 3 == num3 * 4 || ch >= ‘Z’ a) num1 >= 5 || num2 + 3 == num3 5 >= 5 || || ‘K’ >= ‘Z’ 10 == 8 || False False || False 7 + 3 == 2 * 4 True True False b) ‘A’ <= ch && fnum + 7.2 != 2.5 e) num1 < 3 && num2 > num3 ‘A’ <= ‘K’ && 11.75 + 7.2 != 2.5 True && 18.95 True && True 5 < 3 && != 2.5 False False True c) !(3 * num1 + 4 < num3 * 2) !( 3 * 5 + 4 f) num1 > num3 || fnum > num1 + 20 && num3 < 5 11.75 > 5 + 20 && !( 19 < 4) 11.75 > 25 && ! False false True < 2 * 2) 5 >2 True || false || false True There is a short-circuit evaluation of a compound condition when its true value is determined without evaluating all its individual conditions as in a), e), and f) above. Also notice in f) than the && operator has higher precedence than the || operator. In C++, 0 is false and anything else is true. But this is not the case in Java. So, the C++ conditions !num (which is equivalent to num = = 0) is not valid in Java. 8 Precedence of C/C++ Operators Operator Order of Evaluation Precedence ! Unary – right to left 7 left to right 6 left to right 5 left to right 4 == != left to right 3 && left to right 2 || left to right 1 * / % + < <= > <= Accuracy of Floating-Point Values The fact that floating-point values are approximated inside a computer makes it difficult to test for the equality of floating-point values. For example, if the variable fnum is defined as follows: Then, the condition: fnum / 2 == 3.55 float fnum = 7.1; may not be true. The problem may be solved by assuming that two floating-point values are equal if their difference is relatively very small. This is done by testing if the absolute value of their difference is less than a certain value chosen by the programmer (for example 0.000001). Using the library function fabs() that takes as argument a floating-point value and returns its absolute value, the condition: value1 == value2 9 is replaced with the condition: fabs(value1 - value2) < 0.000001 which tests whether the difference between the two values is small enough so that we can make them equal. Conditional Expressions in C/C++ and Java A conditional expression has the following syntax: <Condition > ? <expression-True> : <expression-false> With the meaning: if <Condition> is true, the value of the expression is the value of <expressiontrue> otherwise, it is the value of <expression-false>. Example: average = (count = = 0) ? 0 : sum / count; A conditional expression can be used in a program where any other expression can be used. Example: cin >> num1 >> num2; cout << 2 + (num1 > num2 ? num1/ num2 : num2 / num1); Note that if the inputs are 15 and 3, the output will be 7 and if they are 2 and 7 the output will be 5. Assignment Statements An assignment statement is used to store a value into a memory location. Simple Assignments Examples in C/C++ int num1, num2 = 15, *pt; num2 = num2 * 7; pt = &num1; *pt = num2 / 4; Assignment as an Operator in C/C++ and Java In C-based languages (C/C++ and Java), the assignment is an operator that produces a result which is the same as the value assigned. It has the right-to-left associativity. 10 Examples in C/C++ int num1, num2, num3, ch; char * pt, buffer [81] = {‘\0’}; num1 = num2 = num3 = 5; //assign 5 to the variables num1, num2, and num3 // read values into the buffer until the end-of-file (EOF) character is encountered. pt = buffer; while ( (ch = cin.get( ) ) != EOF) *pt ++ = ch; Compound Assignment Operators in C/C++ and Java They are specified as follows: <variable-name> <operator>= <expression>; Which is equivalent to the regular assignment: <variable-name> = <variable-name> <operator> <expression>; Examples Compound Assignments Equivalent Simple Assignments counter += 5; counter = counter + 5; power *= value; power = power * value; average /= count; average = average / count; total -= value; total = total - value; remain %= 8; remain = remain % 8; result /= num - 25 result = result / (num - 25); number *= -1; number = -number; Conditional Targets in Perl Examples: flag = = 1 ? count1 : count2 = 0; Which means: if (flag = = 1) count1 = 0; else count2 = 0; 11 Multiple Assignments in Perl, Ruby, and Lua These languages provide multiple-target, multiple-source assignment statements. Example The Perl statement: Is executed as follows: ($first, $second, $third) = (10, 20, 30); $first = 10; $second = 20; $third = 30; The statement to interchange the values of two variables can then be written as follows: ($first, $second) = ($second, $first); Mixed-Mode Assignments A mixed-mode assignment is an assignment in which the l-value (variable) and the value of the expression (r-value) do not have the same data type. Example int sum1, num = 5; double sum2, dnum = 12.5; sum1 = dnum + 3,75; sum2 = num + 10; // narrowing conversion // widening conversion Mixed-mode assignments are allowed in Fortran, C, C++, and Perl and its coercion rules are similar to those used for mixed-mode expressions: many of the possible types mixes are legal, with coercions freely applied. Ada does not allow mixed-mode assignments, and Java and C# allow it only if the required coercion is widening conversion. 12 Exercises: 9 page 343 & 344; 13 page 344 and 20 page 345. Extra credits: 2, 3, 4, 5, 6 page 343. Assuming that the variables are defined and initialized as follows: int num1 = 9 , num2 = 5 , num3 = 10; float fnum = 12.50; char ch = ‘P’; A. Evaluate the following conditions (using short circuit evaluation whenever possible): a) 2 * num1 - 5 >= 9 || fnum / 2 + 10 <= 6.5 b) num1 + 5 = = 24 || num1 – 1 > num2 - 5 c) num1 + num2 == num3 + 5 && 2 * num3 <= 4 * num2 d) 2 * num1 - 5 >= 9 && fnum / 2 + 10 <= 6.5 e) num1 - num2 <= num1 / 3 || num1 * num2 > 100 f) ! (num1 + 5 <= 13) g) num1 - 5 >= num3 || num2 < 15 && num1 >= 9 B. Which of the following C++ conditions are equivalent (that means have the same true value)? a) num1 != 0 d) !num1 b) num1 == 0 e) !(num1 == 0) c) num1 13 Major types of Statements in an Imperative Language 1. Input statement: to input data into the computer (program) 2. Output statement: to output information from the computer (program) 3. Assignment statement: to store information/data into a memory location. 4. One way-selection structure: to execute one or more statements when a condition is true 5. two-way-selection structure: condition. to make a choice of action based on the true value of a 6. multiple-way selection structure: or more conditions. to make a choice of action based on the true values of two 7. A counter-controlled iteration: to repeat the execution of one or more statements a fixed number of times. 8. A logically-controlled iteration: to repeat the execution of one or more statements as long as a condition is true. Exercises Chapter 8 1c, 2, 3c, 4, 5, 6, 8, 9 pages 383-385.