370 likes | 383 Views
Chapter 7 : Expression and Assignment Statements. Introduction Arithmetic Expressions Overloaded operators Type Conversions Relational and Boolean Expressions Short-Circuit Evaluation Assignment Statements Mixed-Mode Assignment. Expression and assignment statements.
E N D
Chapter 7 : Expression and Assignment Statements • Introduction • Arithmetic Expressions • Overloaded operators • Type Conversions • Relational and Boolean Expressions • Short-Circuit Evaluation • Assignment Statements • Mixed-Mode Assignment.
Expression and assignment statements • This chapter will focus on expression and assignment statements. • The semantic rules that determine the order of evaluation of operators in expression are discussed first. • This is followed by the potential problems of implementation-defined operand evaluation order when expiration can have side effects.
Overload operators ,both predefined and user-defined ,are then discussed ,along with their effects on expression in programs. • Next ,mixed-mode expressions are discussed and evaluated . • Relational and Boolean expressions are then discussed . • Finally ,the assignment statement from its simplest form to all of its variations , is covered , including assignments as expression and mixed-mode assignments
Introduction • Expressions are the fundamental means of specifying computations in a programming language. • It is crucial for a programmer to understand both the syntax and semantics of expressions. • Methods of describing the syntax of expirations were described in chapter 3
Introduction • In this chapter, we focus on the semantics of expression that is, what they mean, which is determined by how they are evaluated • To understand expression evaluation, it is necessary to be familiar with the order of operator and operand evaluation. • The operator evaluation order of expressions is governed by the associativity and procedure rules of the language. • The essence of an imperative programming language is the dominant role of assignment statements. • The purpose of an assignment statement is to change the value of a variable.
Chapter 7 • Arithmetic Expressions • Their evaluation was one of the motivations for the development of the first programming languages • Arithmetic expressions consist of operators, operands, parentheses, and function calls
Chapter 7 Design issues for arithmetic expressions: • What are the operator precedence rules? • What are the operator associatively rules? • What is the order of operand evaluation? • Are there restrictions on operand evaluation side effects? • Does the language allow user-defined operator overloading? • What mode mixing is allowed in expressions?
In programming languages, arithmetic expression consist of operators, operands, parentheses, and function calls • A unary operator has one operand • A binary operator has two operands • A ternary operator has three operands • C,C++,and Java include a ternary operator which has three operands . • Most imperative programming languages ,binary operators are infix ,which means that they appear between their operands. • One exception is perl which has some operators that are prefix ,which means that they appear precede their operands.
Operator precedence • Def: The operator precedence rules for expression evaluation define the order in which “adjacent” operators of different precedence levels are evaluated (“adjacent” means they are separated by at most one operand) • Typical precedence levels • parentheses • unary operators • ** (if the language supports it) • *, / • +, -
Operator associativity • Def: The operator associativity rules for expression evaluation define the order in which adjacent operators with the same precedence level are evaluated • Typical associatively rules: • Left to right, except **, which is right to left • Sometimes unary operators associate right to left (e.g., FORTRAN) • APL is different; all operators have equal precedence and all operators associate right to left • Precedence and associatively rules can be overridden with parentheses
- Typical associatively rules: - Left to right, except **, which is right to left - Sometimes unary operators associate right to left (e.g., FORTRAN) - APL is different; all operators have equal precedence and all operators associate right to left Precedence and associatively rules can be overridden with parentheses
Operand evaluation order - The process: 1. Variables: just fetch the value 2. Constants: sometimes a fetch from memory; sometimes the constant is in the machine language instruction 3. Parenthesized expressions: evaluate all operands and operators first 4. Function references: The case of most interest! - Order of evaluation is crucial Functional side effects - when a function changes a two-way parameter or a nonlocal variable
The problem with functional side effects: - When a function referenced in an expression alters another operand of the expression e.g., for a parameter change: a = 10; b = a + fun(&a); /* Assume that fun changes its parameter */
Two Possible Solutions to the Problem: 1. Write the language definition to disallow functional side effects - No two-way parameters in functions - No nonlocal references in functions - Advantage: it works! - Disadvantage: Programmers want the flexibility of two-way parameters (what about C?) and nonlocal references 2. Write the language definition to demand that operand evaluation order be fixed - Disadvantage: limits some compiler optimizations
Conditional Expressions - C, C++, and Java (?:) e.g. average = (count == 0)? 0 : sum / count; Operator Overloading: Multiple use of an operator - Generally thought to be acceptable, as long as readability and /or don’t suffer - Some is common (e.g., + for int and float) - Some is potential trouble (e.g., * in C and C++) - Loss of compiler error detection (omission of an operand should be a detectable error) - Can be avoided by introduction of new symbols (e.g., Pascal’s div)
- C++ and Ada allow user-defined overloaded operators Potential problems: - Users can define nonsense operations - Readability may suffer
Implicit Type Conversions Def: A narrowing conversion is one that converts an object to a type that cannot include all of the values of the original type Def: A widening conversion is one in which an object is converted to a type that can include at least approximations to all of the values of the original type Def: A mixed-mode expression is one that has operands of different types Def: A coercion is an implicit type conversion
- The disadvantage of coercions: - They decrease in the type error detection ability of the compiler - In most languages, all numeric types are coerced in expressions, using widening conversions - In Modula-2 and Ada, there are virtually no coercions in expressions
Explicit Type Conversions - Often called casts e.g. Ada: FLOAT(INDEX) -- INDEX is INTEGER type C: (int)speed /* speed is float type */
Errors in Expressions - Caused by: - Inherent limitations of arithmetic e.g. division by zero - Limitations of computer arithmetic e.g. overflow - Such errors are often ignored by the run-time system
Relational Expressions • A relational operator is an operator that compares the values of its two operands. • A relational expression has two operands and one relational operator. • The vale of a relational expression is Boolean ,except when Boolean is not a type in the language. • Use relational operators and operands of various types • Evaluate to some Boolean representation • Operator symbols used vary somewhat among • languages (!=, /=, .NE., <>, #) • The relational operator always have lower precedence than the arithmetic operator.
Boolean Expressions: consist of boolean variables ,boolean constants ,relational expressions ,and boolean operator. • - Operands are boolean and the result is boolean • - Operators: • FORTRAN 77 FORTRAN 90 C Ada • .AND. and && and • .OR. or || or • .NOT. not ! not • xor • - C has no boolean type--it uses int type with 0 • for false and nonzero for true • - One odd characteristic of C’s expressions: • a < b < c is a legal expression, but the • result is not what you might expect
Precedence of All Operators: • Pascal: not, unary - • *, /, div, mod, and • +, -, or • relops • Ada: ** • *, /, mod, rem • unary -, not • +, -, & • relops • and, or, xor • C, C++, and Java have over 50 operators and 17 • different levels of precedence
Short Circuit Evaluation: is one in which the result is determind without evaluating all the operands or operators • E.g. • (13*A)*(b/13-1) • Pascal: does not use short-circuit evaluation • Problem: table look-up • index := 1; • while (index <= length) and • (LIST[index] <> value) do • index := index + 1
C, C++, and Java: use short-circuit evaluation for • the usual Boolean operators (&& and ||), but • also provide bitwise Boolean operators that are • not short circuit (& and |) • Ada: programmer can specify either (short-circuit • is specified with and then and or else) • FORTRAN 77: short circuit, but any side-affected • place must be set to undefined • Short-circuit evaluation exposes the potential • problem of side effects in expressions • e.g. (a > b) || (b++ / 3)
Assignment Statements • The operator symbol: • 1. = FORTRAN, BASIC, PL/I, C, C++, Java • 2. := ALGOLs, Pascal, Modula-2, Ada • = can be bad if it is overloaded for the • relational operator for equality • e.g. (PL/I) A = B = C; • Note difference from C
More complicated assignments: 1. Multiple targets (PL/I) A, B = 10 2. Conditional targets (C, C++, and Java) (first = true) ? total : subtotal = 0 3. Compound assignment operators (C, C++, and Java) sum += next;
More complicated assignments: 4. Unary assignment operators (C, C++, and Java) a++; C, C++, and Java treat = as an arithmetic binary operator e.g. a = b * (c = d * 2 + 1) + 1 This is inherited from ALGOL 68
Assignment as an Expression - In C, C++, and Java, the assignment statement produces a result - So, they can be used as operands in expressions e.g. while ((ch = getchar() != EOF) { ... } Disadvantage - Another kind of expression side effect
Mixed-Mode Assignment - In FORTRAN, C, and C++, any numeric value can be assigned to any numeric scalar variable; whatever conversion is necessary is done - In Pascal, integers can be assigned to reals, but reals cannot be assigned to integers (the programmer must specify whether the conversion from real to integer is truncated or rounded) - In Java, only widening assignment coercions are done - In Ada, there is no assignment coercion
Q21: Consider the following C program int fun(int * I) { *I + = 5; return 4; } void main( ) { int x; x = x + fun(&x); } What is the value of x after the assignment statement in main assuming: a- operands are evaluated left to right. b- operands are evaluated right to left.
int fun(int * I) { *I + = 5; return 4; } void main( ) { int x=3; x = x + fun(&x); } left to right = 7 right to left = 12
Q19 : Should an optimizing compiler for C or C++ be allowed to change the order of subexpressions in Boolean expression ? Why or why not ?
I think yes, Consider : a < b < c . This statement is legal. What it will compare is a < b . The answer will be either 0 or 1. Now this number will be compared with c. Thus there is no comparison at all between b and c.
Q15: Let the C function be defined as : int fun(int * k) { *k += 4; return 3* (*k) - 1; } Suppose fun is used in a program as follows: void main() { int i = 10, j = 10, sum1, sum2; sum1 = ( i/2) + fun(&i); sum2 = fun(&j) + ( j/20); } Determine the values of sum1 and sum2 by running the program on a computer. Explain the results ?
#include<stdio.h> int fun(int * k) { *k += 4; return 3* (*k) - 1; } void main() { int i = 10, j = 10, sum1, sum2; sum1 = ( i/2) + fun(&i); sum2 = fun(&j) + ( j/20); } 46 41