Expressions and Assignments
Expressions and Assignments
Introduction
Expressions in programming languages are fundamental constructs for specifying
computations. They consist of operators and operands, and their syntax and semantics
are crucial for understanding how computations are performed in a given language.
The semantics of expressions deal with how expressions are evaluated, including
the order of evaluation for operators and operands. Operator evaluation order is
determined by associativity and precedence rules defined by the language. Operand
evaluation order, on the other hand, is often left unspecified by language designers,
allowing implementors flexibility in choosing the order, which can lead to potential
differences in program behaviour across implementations.
The value of an expression depends at least in part on the order of evaluation of the
operators in the expression.
Consider the following expression: a + b * c Suppose the variables a, b, and c have
the values 3, 4, and 5, respectively. If evaluated left to right (the addition first and
then the multiplication), the result is 35. If evaluated right to left, the result is 23.
Operator Precedence Hierarchy: In most programming languages, operators are
assigned a precedence level based on their complexity and mathematical convention.
For example, multiplication typically has a higher precedence than addition because
it's considered more complex.
Unary Operators: Unary operators are operators that act on a single operand.
Common unary operators include unary addition (identity operator) and unary minus
(negation). Unary minus changes the sign of its operand. Unary addition usually has
no effect on its operand.
Placement of Unary Operators: Unary operators like unary minus can appear either
at the beginning of an expression or anywhere inside the expression, as long as they
are properly parenthesized to avoid ambiguity with other operators.
Implicit Type Conversion: In some languages like Java and C#, unary minus not
only changes the sign of its operand but also causes implicit type conversion for
certain data types. For example, unary minus may cause the conversion of short and
byte operands to int type. Unary addition is called the identity operator because it usually
has no associated operation and thus has no effect on its operand.
For example,
a + (- b) * c
is legal, but
a+-b*c
usually is not.
In the first two cases, the relative precedence of the unary minus operator and the
binary operator is irrelevant—the order of evaluation of the two operators has no
effect on the value of the expression.
Only Fortran, Ruby, Visual Basic, and Ada have the exponentiation operator. In all
four, exponentiation has higher precedence than unary minus, so
- A ** B
is equivalent to
-(A ** B)
The precedence’s of the arithmetic operators of Ruby and the C-based languages are
as follows:
Ruby C-Based Languages
Highest ** postfix ++, --
unary +,- prefix ++, --, unary +, -
*, /, % *, /, %
Lowest binary +, - binary +, -
The ** operator is exponentiation. The % operator takes two integer operands and
yields the remainder of the first after division by the second.
Associativity
Java expression
a-b+c
the left operator is evaluated first.
The associativity rules for a few common languages are given here
Parentheses:
Precedence Override:
Parentheses allow programmers to specify the order of evaluation within an
expression, regardless of the default precedence of operators.
Avoiding Overflow:
Parentheses can also be used to prevent overflow or clarify the intended order of
evaluation.
By grouping operations within parentheses, programmers can explicitly define the
sequence of computations, as shown in (A + B) + (C + D). This can improve code
clarity and prevent unexpected results, especially in complex expressions.
Ruby Expressions:
In Ruby
Expressions in LISP
Conditional Expressions
Conditional
Expressions:
– a ternary operator in C-based languages (e.g., C, C++)
– An example:
Side Effects
A side effect of a function, called a functional side effect, occurs when the
function changes either one of its parameters or a global variable.
(A global variable is declared outside the function but is accessible in the function.)
a = 10;
b = a + fun(a);
Then, if the value of a is fetched first (in the expression evaluation process), its value
is 10 and the value of the expression is 20.
But if the second operand is evaluated first, then the value of the first operand is
20 and the value of the expression is 30.