Expressions and Statements: Arithmetic Expressions, Overloaded Operators, Type Conversions, Relational and Boolean
Expressions, Short Circuit Evaluation, Assignment Statements, Mixed-Mode Assignment
Expressions and Statements Arithmetic Expressions:
– Arithmetic evaluation was one of the motivations for computers
– In programming languages, arithmetic expressions consist of operators,
operands, parentheses, and function calls.
– An operator can be unary, meaning it has a single operand, binary, meaning it has two
operands, or ternary, meaning it has three operands.
– In most programming languages, binary operators are infix, which means they
appear between their operands.
– One exception is Perl, which has some operators that are prefix, which means
they precede their operands.
– The purpose of an arithmetic expression is to specify an arithmetic computation
– An implementation of such a computation must cause two actions: fetching the
operands, usually from memory, and executing arithmetic operations on those operands.
– Arithmetic expressions consist of
– operators
– operands
– parentheses
– function calls
Issues for Arithmetic Expressions:
– operator precedence rules
– operator associatively rules
– order of operand evaluation
– operand evaluation side effects
– operator overloading
– mode mixing expressions
Operators:
A unary operator has one operand
– unary -, !
– A binary operator has two operands
– +, -, *, /, %
A ternary operator has three operands - ?:
Conditional Expressions:
– a ternary operator in C-based languages (e.g., C, C++)
– An example:
average = (count == 0)? 0 : sum / count
– Evaluates as if written like
if (count == 0) average = 0 else average = sum /count
Operator Precedence Rules:
– Precedence rules define the order in which ―adjacent‖ operators of different
precedence levels are evaluated
– Typical precedence levels
– parentheses
– unary operators
– ** (if the language supports it)
Operator Associatively Rules:
– Associativity rules define the order in which adjacent operators with the
same precedence level are evaluated
– Typical associativity rules
– Left to right for arithmetic operators
– exponentiation (** or ^) is right to left
– Sometimes unary operators associate right to left (e.g., in FORTRAN)
– APL is different; all operators have equal precedence and all operators associate right to
left
– Precedence and associativity rules can be overriden with parentheses
Operand Evaluation Order:
– Variables: fetch the value from memory
– Constants: sometimes a fetch from memory; sometimes the constant is in the machine
language instruction
– Parenthesized expressions: evaluate all operands and operators first
Potentials for Side Effects:
– Functional side effects: when a function changes a two-way parameter or a non-local
variable
– 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;
/* assume that fun changes its parameter */ b = a + fun(a);
Functional Side Effects:
– Two possible solutions to the problem
Write the language definition to disallow functional side effects
No two-way parameters in functions
No non-local references in functions
Advantage: it works!
Disadvantage: inflexibility of two-way parameters and non-local
references
Write the language definition to demand that operand evaluation order be fixed
Disadvantage: limits some compiler optimizations
Overloaded Operators:
– Use of an operator for more than one purpose is called operator overloading
– Some are common (e.g., + for int and float)
– Some are potential trouble (e.g., * in C and C++)
– Loss of compiler error detection (omission of an operand should be a
detectable error)
– Some loss of readability
– Can be avoided by introduction of new symbols (e.g., Pascal‘s div for
integer division)
Type Conversions
A narrowing conversion converts an object to a type that does not include all of the values
of the original type
– e.g., float to int
– A widening conversion converts an object to a type that can include at
least approximations to all of the values of the original type
– e.g., int to float
Coercion:
– A mixed-mode expression is one that has operands of different types
– A coercion is an implicit type conversion
– Disadvantage of coercions:
– They decrease in the type error detection ability of the compiler
– In most languages, widening conversions are allowed to happen implicitly
– In Ada, there are virtually no coercions in expressions
Casting:
– Explicit Type Conversions
– Called casting in C-based language
– Examples
– C: (int) angle
– Ada: Float (sum)
Note that Ada’s syntax is similar to function calls
CREC, Dept. of CSE Page 6
Errors in Expressions:
Causes
– Inherent limitations of arithmetic e.g., division by zero, round-off errors
– Limitations of computer arithmetic e.g. overflow
– Often ignored by the run-time system
Relational Operators:
– Use operands of various types
– Evaluate to some Boolean representation
– Operator symbols used vary somewhat among languages (!=, /=, .NE., <>, #)
Boolean Operators:
– Operands are Boolean and the result is Boolean
– Example operators
FORTRAN 77 FORTRAN 90 C Ada
AND .and && and
OR .or || or
.NOT .not ! not
No Boolean Type in C:
– C has no Boolean type
– it uses int type with 0 for false and nonzero for true
Consequence
– a < b < c is a legal expression
– the result is not what you might
expect: Left operator is evaluated, producing 0 or 1
– This result is then compared with the third operand (i.e., c)
CREC, Dept. of CSE Page 7
Precedence of C-based operators:
postfix ++, --
unary +, -, prefix ++, --, !
*,/,% binary +, -
<, >, <=, >=
=, !=
&&
||
Short Circuit Evaluation:
• Result is determined without evaluating all of the operands and/or operators
– Example: (13*a) * (b/13–1)
If a is zero, there is no need to evaluate (b/13-1)
– Usually used for logical operators
– Problem with non-short-circuit evaluation
While (index <= length) && (LIST[index] != value) Index++;
– When index=length, LIST [index] will cause an indexing problem (assuming
LIST has length -1 elements)
Mixed-Mode Assignment:
Assignment statements can also be mixed-mode, for example int a, b; float c; c = a / b;
– In Java, only widening assignment coercions are done
– In Ada, there is no assignment coercion
CREC, Dept. of CSE Page 8
Assignment Statements:
The general syntax
<target_var> <assign_operator> <expression>
The assignment operator
– FORTRAN, BASIC, PL/I, C, C++, Java := ALGOLs, Pascal, Ada
= can be bad when it is overloaded for the relational operator for equality
Compound Assignment:
– A shorthand method of specifying a commonly needed form of assignment
– Introduced in ALGOL; adopted by C
– Example a = a + b is written as a += b
Unary Assignment Operators:
– Unary assignment operators in C-based languages combine increment and
decrement operations with assignment
– These have side effects
– Examples
sum = ++count (count incremented, added to sum) sum = count++ (count added to sum,
incremented) Count++ (count incremented) -count++ (count incremented then negated - right-
associative)
Assignment as an Expression:
– In C, C++, and Java, the assignment statement produces a result and can be used
as operands
– An example:
While ((ch = get char ())!= EOF){…}
ch = get char() is carried out; the result (assigned to ch) is used in the condition for the while
CREC, Dept. of CSE Page 9
statement
Control Statements: Evolution
FORTRAN I control statements were based directly on IBM 704 hardware
– Much research and argument in the 1960s about the issue
One important result: It was proven that all algorithms represented by flowcharts can be
coded with only two-way selection and pretest logical loops
Control Structure
– A control structure is a control statement and the statements whose execution it controls
– Design question
–Should a control structure have multiple entries?
Selection Statements
– A selection statement provides the means of choosing between two or more paths
of execution
– Two general categories:
– Two-way selectors
– Multiple-way selectors
CREC, Dept. of CSE Page 10
Two-Way Selection Statements
General form:
If control_expression then clause else clause
Design Issues:
– What is the form and type of the control expression?
– How are the then and else clauses specified?
– How should the meaning of nested selectors be specified?
The Control Expression
– If the then reserved word or some other syntactic marker is not used to introduce the
then clause, the control expression is placed in parentheses
– In C89, C99, Python, and C++, the control expression can be arithmetic
– In languages such as Ada, Java, Ruby, and C#, the control expression must be Boolean
Clause Form
– In many contemporary languages, the then and else clauses can be single statements
or compound statements
– In Perl, all clauses must be delimited by braces (they must be compound)
– In Fortran 95, Ada, and Ruby, clauses are statement sequences
– Python uses indentation to define clauses if x > y
:x=y
print "case 1"
Nesting Selectors
– Java example
if ( sum == 0) if ( count == 0) result =
0; else result = 1;
CREC, Dept. of CSE Page 11
– Which if gets the else?
– Java's static semantics rule: else matches with the nearest if Nesting Selectors (continued)
– To force an alternative semantics, compound statements may be used: if (sum == 0) {
if (count == 0) result = 0;
else result = 1;
– The above solution is used in C, C++, and C#
– Perl requires that all then and else clauses to be compound
– Statement sequences as clauses: Ruby if sum == 0
then if count == 0 then result = 0
else result = 1 end
end
• Python
if sum == 0 :
if count == 0 : result = 0
else : result = 1
Multiple-Way Selection Statements
• Allow the selection of one of any number of statements or statement groups
Design Issues:
– What is the form and type of the control expression?
– How are the selectable segments specified?
– Is execution flow through the structure restricted to include just a single selectable segment?
– How are case values specified?
– What is done about unrepresented expression values?
CREC, Dept. of CSE Page 12
Multiple-Way Selection: Examples
• C, C++, and Java switch (expression) { case
const_expr_1: stmt_1;
case const_expr_n: stmt_n; [default: stmt_n+1]
– Design choices for C‗s switch statement
– Control expression can be only an integer type
– Selectable segments can be statement sequences, blocks, or compound statements
– Any number of segments can be executed in one execution of the construct (there is
no implicit branch at the end of selectable segments)
– default clause is for unrepresented values (if there is no default, the whole statement does
nothing)
Multiple-Way Selection: Examples
– C#
Differs from C in that it has a static semantics rule that disallows the implicit execution
of more than one segment
Each selectable segment must end with an unconditional branch (goto or break)
– Ada
case expression is
when choice list => stmt_sequence;
when choice list => stmt_sequence; when others => stmt_sequence;] end case;
– More reliable than C‗s switch (once a stmt_sequence execution is completed, control
is passed to the first statement after the case statement
CREC, Dept. of CSE Page 13
Ada design choices:
– Expression can be any ordinal type
– Segments can be single or compound
– Only one segment can be executed per execution of the construct
– Unrepresented values are not allowed
Constant List Forms:
– A list of constants
– Can include:
Subranges
Boolean OR operators (|)
Multiple-Way Selection Using if
– Multiple Selectors can appear as direct extensions to two-way selectors, using else-
if clauses, for example in Python: if count < 10 : bag1 = True
elsif count < 100 : bag2 = True
elif count < 1000 : bag3 = True
Iterative Statements
– The repeated execution of a statement or compound statement is accomplished either
by iteration or recursion
– General design issues for iteration control statements:
– How is iteration controlled?
– Where is the control mechanism in the loop?
Counter-Controlled Loops
A counting iterative statement has a loop variable, and a means of specifying the initial and
terminal, and stepsize values
CREC, Dept. of CSE Page 14
– Design Issues:
What are the type and scope of the loop variable?
What is the value of the loop variable at loop termination?
Should it be legal for the loop variable or loop parameters to be changed in the loop
body, and if so, does the change affect loop control?
Should the loop parameters be evaluated only once, or once for every iteration?
Iterative Statements: Examples
FORTRAN 95 syntax
DO label var = start, finish [, stepsize]
Stepsize can be any value but zero
Parameters can be expressions
– Design choices:
Loop variable must be INTEGER
Loop variable always has its last value
The loop variable cannot be changed in the loop, but the parameters can; because they
are evaluated only once, it does not affect loop control
Loop parameters are evaluated only once
FORTRAN 95 : a second form:
[name:] Do variable = initial, terminal [,stepsize]
End Do [name]
- Cannot branch into either of Fortran‗s Do statements
Ada
CREC, Dept. of CSE Page 15
for var in [reverse] discrete_range loop ... end loop
• Design choices:
– Type of the loop variable is that of the discrete range (A discrete range is a sub-range of
an integer or enumeration type).
– Loop variable does not exist outside the loop
– The loop variable cannot be changed in the loop, but the discrete range can; it does not
affect loop control
– The discrete range is evaluated just once
– Cannot branch into the loop body
– C-based languages
for ([expr_1] ; [expr_2] ; [expr_3]) statement
– The expressions can be whole statements, or even statement sequences, with
the statements separated by commas
– The value of a multiple-statement expression is the value of the last statement in
the expression
– If the second expression is absent, it is an infinite loop
Design choices:
– There is no explicit loop variable
– Everything can be changed in the loop
– The first expression is evaluated once, but the other two are evaluated with each
iteration C++ differs from C in two ways:
– The control expression can also be Boolean
– The initial expression can include variable definitions (scope is from the definition to
the end of the loop body)
– Java and C#
Differs from C++ in that the control expression must be Boolean
CREC, Dept. of CSE Page 16
Iterative Statements: Logically-Controlled Loops
Repetition control is based on a Boolean
expression Design issues:
– Pretest or posttest?
– Should the logically controlled loop be a special case of the counting
loop statement or a separate statement?
Iterative Statements: Logically-Controlled Loops: Examples
C and C++ have both pretest and posttest forms, in which the control
expression can be arithmetic:
while (ctrl_expr) do loop body loop body while (ctrl_expr)
Java is like C and C++, except the control expression must be Boolean (and the body
can only be entered at the beginning -- Java has no goto
Iterative Statements: Logically-Controlled Loops: Examples
Ada has a pretest version, but no posttest
FORTRAN 95 has neither
Perl and Ruby havetwo pretest logical loops, while and until. Perl also has two posttest
loops
Iterative Statements: User-Located Loop Control Mechanisms
Sometimes it is convenient for the programmers to decide a location for loop
control (other than top or bottom of the loop)
Simple design for single loops (e.g., break)
Design issues for nested loops
Should the conditional be part of the exit?
Should control be transferable out of more than one loop?
CREC, Dept. of CSE Page 17
Iterative Statements: User-Located Loop Control Mechanisms break and continue
C , C++, Python, Ruby, and C# have unconditional unlabeled exits (break)
Java and Perl have unconditional labeled exits (break in Java, last in Perl)
C, C++, and Python have an unlabeled control statement, continue, that skips the
remainder of the current iteration, but does not exit the loop
Java and Perl have labeled versions of continue Iterative Statements: Iteration Based
on Data Structures
Number of elements of in a data structure control loop iteration
Control mechanism is a call to an iterator function that returns the next element in
some chosen order, if there is one; else loop is terminate
C's for can be used to build a user-defined iterator: for (p=root; p==NULL; traverse(p)){}
C#‗s foreach statement iterates on the elements of arrays and other collections:
Strings[] = strList = {"Bob", "Carol", "Ted"}; foreach (Strings name in strList)
Console.WriteLine ("Name: {0}", name);
- The notation {0} indicates the position in the string to be displayed
– Perl has a built-in iterator for arrays and hashes, foreach Unconditional Branching
– Transfers execution control to a specified place in the program
– Represented one of the most heated debates in 1960‗s and 1970‗s
– Well-known mechanism: goto statement
– Major concern: Readability
– Some languages do not support goto statement (e.g., Java)
– C# offers goto statement (can be used in switch statements)
– Loop exit statements are restricted and somewhat camouflaged goto‗s
Guarded Commands
Designed by Dijkstra
Purpose: to support a new programming methodology that supported
verification (correctness) during development
Basis for two linguistic mechanisms for concurrent programming (in CSP and Ada)
CREC, Dept. of CSE Page 18
Basic Idea: if the order of evaluation is not important, the program should not specify one
CREC, Dept. of CSE Page 19
Selection Guarded Command
•Form
if <Boolean exp> -> <statement> [] <Boolean exp> -> <statement>
...
[] <Boolean exp> -> <statement> fi
•Semantics: when construct is reached,
–Evaluate all Boolean expressions
–If more than one are true, choose one non-deterministically
–If none are true, it is a runtime error Selection Guarded Command: Illustrated
Loop Guarded
Command
Form
do <Boolean> ->
<statement> []
<Boolean> ->
<statement>
...
[] <Boolean> ->
<statement> od
Semantics: for each
iteration
1. Evaluate all Boolean expressions
2. If more than one are true, choose one non-deterministically; then start loop
again
3. If none are true, exit loop
Guarded Commands: Rationale
CREC, Dept. of CSE Page 20
Connection between control statements and program verification is intimate
Verification is impossible with goto statements
Verification is possible with only selection and logical pretest loops
Verification is relatively simple with only guarded commands
CREC, Dept. of CSE Page 21