0% found this document useful (0 votes)
26 views51 pages

Expressions and Assignment Statements Programming Languages

Expressions are essential for computations in programming languages, requiring an understanding of operator and operand evaluation. Arithmetic expressions, which include operators, operands, and function calls, follow mathematical conventions and are crucial for specifying calculations. Operator precedence, associativity, and the use of parentheses influence how expressions are evaluated, while conditional expressions provide a shorthand for if-then-else statements.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
26 views51 pages

Expressions and Assignment Statements Programming Languages

Expressions are essential for computations in programming languages, requiring an understanding of operator and operand evaluation. Arithmetic expressions, which include operators, operands, and function calls, follow mathematical conventions and are crucial for specifying calculations. Operator precedence, associativity, and the use of parentheses influence how expressions are evaluated, while conditional expressions provide a shorthand for if-then-else statements.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 51

PROGRAMMING LANGUAGES

EXPRESSIONS AND ASSIGNMENT


STATEMENTS

1
Introduction

 Expressions are the fundamental means of specifying computations in a


programming language.

 To understand expression evaluation, need to be familiar with the orders


of operator and operand evaluation.

 Essence of imperative languages is dominant role of assignment


statements.

Expressions and Assignment Statements

"Expressions are the fundamental means of specifying computations in a programming language."


In programming, expressions are the main way we tell the computer to do something (like add numbers, compare
values, or call functions).

2. "To understand expression evaluation, need to be familiar with the orders of operator and operand
evaluation."
To understand how the computer solves an expression, you need to know which parts it looks at first — like which
operator (e.g., +, *) or value (called an operand) it uses first.

3. "Essence of imperative languages is dominant role of assignment statements."


In programming languages like C, Java, or Python (called imperative languages), the most important part is using
assignment statements — these are lines like x = 5 that tell the computer to store a value in a variable.

2
Arithmetic Expressions

 Arithmetic evaluation was one of the motivations for the development of the first
programming languages.

 Most of the characteristics of arithmetic expressions in programming languages were


inherited from conventions that had evolved in mathematics.

 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.
– C-based languages include a ternary operator, which has three operands
(conditional expression).

EX: x = (a > b) ? a : b;
- If a is greater than b, then x gets a; otherwise, x gets b.

Expressions and Assignment Statements

"Arithmetic evaluation was one of the motivations for the development of the first programming languages."
One reason early programming languages were made was to help computers solve math problems (like addition, subtraction, etc.).
"Most of the characteristics of arithmetic expressions in programming languages were inherited from conventions that had evolved in
mathematics."
The way we write math expressions in programming (like a + b * c) mostly follows math rules we already use, like order of operations.
"Arithmetic expressions consist of operators, operands, parentheses, and function calls."
A math expression in code usually has:
•Operators (like +, -, *, /)
•Operands (the values or variables being used)
•Parentheses (to group parts of the expression)
•Function calls (like sqrt(9) or pow(2, 3))
"An operator can be unary, meaning it has a single operand, binary, meaning it has two operands, or ternary, meaning it has three
operands.“
Operators come in different types:
•Unary: uses 1 value (like -x)
•Binary: uses 2 values (like a + b)
•Ternary: uses 3 values
"C-based languages include a ternary operator, which has three operands (conditional expression)."
Programming languages like C, Java, or JavaScript have a special ternary operator used for conditions.

3
Arithmetic Expressions

 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 from memory


– Executing the arithmetic operations on those operands.

Expressions and Assignment Statements

"The purpose of an arithmetic expression is to specify an arithmetic computation."


The main reason we use arithmetic expressions in code is to tell the computer to do some math, like adding,
subtracting, multiplying, etc.

"An implementation of such a computation must cause two actions:"


To make the math happen, the computer needs to do two things.
– "Fetching the operands from memory"
First, the computer gets the numbers or values (called operands) from where they’re stored (like variables in
memory).
– "Executing the arithmetic operations on those operands."
Second, it does the math operation (like add, subtract, etc.) using the values it just fetched.

4
Design Issues for arithmetic expressions

 What are the operator precedence rules?

 What are the operator associativity 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?

Expressions and Assignment Statements

1. What are the operator precedence rules?


This asks: Which operators should be done first?
For example, in 2 + 3 * 4, should it add first or multiply first?
(Answer: Multiply first, because * has higher precedence than +.)
2. What are the operator associativity rules?
This asks: If operators have the same priority, which direction should we go — left to right or right to left?
Example: a - b - c
If it goes left to right, it becomes (a - b) - c
If right to left, it becomes a - (b - c)
(Most arithmetic operators go left to right.)
3. What is the order of operand evaluation?
This asks: Which operand should be looked at or computed first?
For example, in f() + g(), should f() run before g() or the other way around?
4. Are there restrictions on operand evaluation side effects?
This asks: Can operands change values when they’re being used?
For example, if a function changes a variable while it’s being evaluated, does the language allow that?
(Side effects can cause confusing bugs, so some languages limit them.)
5. Does the language allow user-defined operator overloading?
This asks: Can a programmer change what an operator (like + or *) does for their own types?
Example in C++: You can define how + works for your custom class (like adding two objects).
6. What mode mixing is allowed in expressions?
This asks: Can you mix different data types in one expression?
For example, is int + float or string + number allowed?
Some languages auto-convert types; others don't.

5
Operator Evaluation Order

 Precedence

 Associativity

 Parentheses

 Expressions in Lisp

 Conditional Expressions

Expressions and Assignment Statements

Operator Evaluation Order


This tells the computer how to solve complex expressions — in what order it should apply operators, and how it handles grouped parts.
1. Precedence
Tells which operator goes first when there's more than one.
Example: In 2 + 3 * 4, the * happens before +.
2. Associativity
Tells which direction to go when two operators have the same precedence.
Example: In a - b - c, subtraction is left-to-right, so it's (a - b) - c.
3. Parentheses
Overrides precedence and associativity.
Whatever is in parentheses is solved first.
Example: (2 + 3) * 4 means add first, then multiply.
4. Expressions in Lisp
In Lisp, expressions use prefix notation (operator comes first).
Example: (+ 2 3) means 2 + 3
Every expression is written in the form (operator operand1 operand2 ...)
Conditional Expressions
These expressions choose a value based on a condition. EX: x = (a > b) ? a : b;

6
Precedence

– The operator precedence rules for expression evaluation define the order in
which the operators of different precedence levels are evaluated.

– Many languages also include unary versions of addition and subtraction.

– Unary addition (+) is called the identity operator because it usually has no
associated operation and thus has no effect on its operand.

– In Java and C#, unary minus also causes the implicit conversion of short and
byte operands to int type.

– In all of the common imperative languages, the unary minus operator can
appear in an expression either at the beginning or anywhere inside the
expression, as long as it is parenthesized to prevent it from being next to
another operator.

Expressions and Assignment Statements

1. "The operator precedence rules for expression evaluation define the order in which the operators of different
precedence levels are evaluated.“
Precedence decides which operator goes first when there are multiple kinds in one expression.
Example: In 2 + 3 * 4, multiplication happens before addition.
2. "Many languages also include unary versions of addition and subtraction."
Some languages allow + or - with just one value, like -x or +x. These are called unary operators.
3. "Unary addition (+) is called the identity operator because it usually has no associated operation and thus has no effect
on its operand."
Writing +x does nothing — it’s like saying, “keep it the same.” That’s why it’s called the identity operator.
4. "In Java and C#, unary minus also causes the implicit conversion of short and byte operands to int type."
In Java or C#, when you use - on smaller number types (like byte or short), they automatically turn into int type before doing
the math.
5. "In all of the common imperative languages, the unary minus operator can appear in an expression either at the
beginning or anywhere inside the expression, as long as it is parenthesized to prevent it from being next to another
operator."
You can use - to make a number negative anywhere in an expression, but if it’s near another operator, use parentheses to
avoid confusion.
Example: x * (-y) is OK, but x * - y without parentheses may be unclear.

7
Precedence

For example, unary minus operator (-):

A + (- B) * C // is legal
A+-B*C // is illegal

– Exponentiation has higher precedence that unary minus, so

-A ** B

Is equivalent to

-(A ** B)

Expressions and Assignment Statements

1. A + (-B) * C is legal
This is correct because -B is inside parentheses, so it's clear you're using unary minus on B.

2. A + - B * C is illegal
This can be confusing to the compiler because there's no parentheses, and it’s not clear how to handle - B * C.

Operator Precedence with Exponentiation


3. Exponentiation (**) has higher precedence than unary minus.
This means power is done first, before applying the minus.

4. So, -A ** B is the same as -(A ** B)


First, compute A to the power of B, then apply the negative sign to the result.

Example:
If A = 2, B = 3, then:
-A ** B = -(2 ** 3) = -8

8
Precedence

The precedences of the arithmetic operators of Ruby and the C-based


languages are as follows:

Expressions and Assignment Statements

9
Associativity

– The operator associativity rules for expression evaluation define the order in
which adjacent operators with the same precedence level are evaluated. An
operator can be either left or right associative.

– Typical associativity rules:


 Left to right, except **, which is right to left
 Sometimes unary operators associate right to left (e.g., Fortran)

– Ex: Java

a–b+c //left to right

Expressions and Assignment Statements

When two or more operators have the same strength (same precedence), which one happens first?

Left to Right associativity:


Solve from left side going to right side.
•First: a - b
•Then: result + c
Because - and + have the same strength, and associativity is left to right.

Right to Left associativity:


Solve from the right side first.
Example (Ruby and others):
•First: 3 ** 2 = 9
•Then: 2 ** 9 = 512
Because ** (exponentiation) is right to left. If it were left to right, you'd get a different wrong answer.

10
Associativity

– Ex: Fortran

A ** B ** C // right to left
(A ** B) ** C // in Ada it must be parenthesized

Expressions and Assignment Statements

11
Associativity

– The associativity rules for a few common languages are given here:

Expressions and Assignment Statements

12
Associativity

– APL is different; all operators have equal precedence and all operators
associate right to left.

– Ex: APL

AxB+C // A = 3, B = 4, C = 5  27

– Precedence and associativity rules can be overridden with parentheses.

Expressions and Assignment Statements

13
Parentheses

– Programmers can alter the precedence and associativity rules by placing


parentheses in expressions.

– A parenthesized part of an expression has precedence over its adjacent


unparenthesized parts.

– Ex:

(A + B) * C // addition will be evaluated first

Expressions and Assignment Statements

Parentheses in programming are like giving special importance to something.


Whatever is inside parentheses will be solved first, no matter what the usual precedence and associativity rules
are.

14
Expressions in Lisp

– All arithmetic and logic operations are by explicitly called subprograms

– Ex: to specify the c expression a + b * c in Lisp, one must write the following
expression:

(+ a (* b c)) // + and * are the names of functions

Expressions and Assignment Statements

In some languages like Lisp,


Arithmetic and logic operations are not special symbols (+, *, -, etc.).
They are just functions you call.

Normally in C, Java, Ruby, etc., you write: a + b * c

In Lisp, you have to call the functions directly: (+ a (* b c))


* is a function that multiplies b and c.
+ is a function that adds a and the result of (* b c).

15
Conditional Expressions

– Sometimes if-then-else statements are used to perform a conditional


expression assignment.

– Ex: C-based languages

if (count == 0)
average = 0;
else
average = sum / count;

Expressions and Assignment Statements

Conditional expression assignment means:


Choosing what value to assign based on a condition.

16
Conditional Expressions

– In the C-based languages, this can be specified more conveniently in an


assignment statement using a conditional expression. Note that ? is used in
conditional expression as a ternary operator (3 operands).

expression_1 ? expression_2 : expression_3

– Ex:

average = (count == 0) ? 0 : sum / count;

Expressions and Assignment Statements

instead of writing a long if-else, you can use a ternary operator ? : for shorter code.

expression_1 ? expression_2 : expression_3


• If expression_1 is true, use expression_2.
• If expression_1 is false, use expression_3.

average = (count == 0) ? 0 : sum / count;


• If count == 0 is true, set average = 0.
• If count == 0 is false, set average = sum / count.

17
Operand evaluation order

 Variables: fetch the value form memory

 Constants: sometimes a fetch from memory; sometimes the constant in


the machine language instruction and not require a memory fetch.

 Parenthesized expression: evaluate all operands and operators first

Expressions and Assignment Statements

When you use a variable (like x or count), the computer fetches (gets) its value from memory.
•Example: If x = 5, when you write y = x + 2, the computer looks up x in memory, finds 5, and uses it.

Constants:
Constants are fixed values (like 5, 10, or 'A').
•Sometimes, the constant is already inside the machine's instruction (no need to fetch from memory).
•Sometimes, if it's a big or special constant, it might still be fetched from memory.

18
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.

 Ex: a + fun(a)
• If fun does not have the side effect of changing a, then the order of
evaluation of the two operands, a and fun(a), has no effect on the
value of the expression. However, if fun changes a, there is an effect.

When we say fun(a),


fun is just the name of a function — like a mini-program — that does two things:
What fun(a) is supposed to do (based on your example):

Return the number 10


Change the value of a to 20

Expressions and Assignment Statements

Functional side effect means:


A function changes something outside itself, like:
•Changing a parameter (input value),
•Changing a global variable (a variable shared by the whole program).

EX: a + fun(a)

If fun(a) does not change a:


•It doesn't matter if you evaluate a first or fun(a) first — result stays the same.

BUT
If fun(a) changes a (like setting a = 0 inside fun):
•Then order matters!
•Because a's value changes before or after the addition, causing different results.

Why is it important?
If functions have side effects, programs can behave differently based on what gets evaluated first.

19
Side Effects

 Ex:

 Consider the following situation: fun returns 10 and changes its parameter
to have the value 20, and:

a = 10;
b = a + fun(a);

Expressions and Assignment Statements

Given:
•fun(a) returns 10
•fun(a) changes a to 20

**Now, depending on the order of evaluation, two things can happen:


If a is evaluated first:
•Get a's value → 10
•Then call fun(a):
• fun returns 10
• fun changes a to 20
•Now compute b = 10 + 10 = 20

If fun(a) is evaluated first:


•Call fun(a) first:
• fun returns 10
• fun changes a to 20
•Then get a's value → now 20 (because fun changed it)
•Now compute b = 20 + 10 = 30

20
Side Effects

• 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 (a + fun(a)= 10 + 10).

• 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 (a + fun(a)= 20 + 10).

Expressions and Assignment Statements

21
Side Effects

 Two possible solutions to the functional side effects problem:


• Write the language definition to disallow functional side effects
• Write the language definition to demand that operand evaluation
order be fixed

 Java guarantees that operands are evaluated in left-to-right order,


eliminating this problem.

Expressions and Assignment Statements

Functional side effects occur when a function modifies something (like a parameter or a global variable) while also returning a result. This
can cause confusion because the order of evaluation matters — the program might behave differently depending on which part of the
expression is evaluated first.
Two Possible Solutions to This Problem:
1.Disallow functional side effects in the language
1. The language design could prohibit functions from modifying parameters or global variables. This would eliminate side
effects and ensure that functions are pure (i.e., they always return the same output for the same input and don’t change
anything else).
2. Example:
If side effects are not allowed, a function like fun(a) in C would not be allowed to change a. It would just return a value and
leave everything else alone.
2. Fix operand evaluation order in the language
•The language can define a strict order for evaluating operands in expressions. For example, Java guarantees that operands are always
evaluated in left-to-right order.
•This means in Java, the expression a + fun(a) will always evaluate a first, and then fun(a), making the evaluation predictable and
consistent. You don’t have to worry about the order causing problems.
In Java, the order of operand evaluation is fixed as left-to-right. This means:
•When you write a + fun(a), Java will always evaluate a first, then fun(a).
•Even if fun(a) changes a, Java ensures that the operands are evaluated in a predictable sequence, which avoids unexpected results due
to side effects.

22
Overloaded Operators

 The use of an operator for more than one purpose is operator overloading.

 Some are common (e.g., + for int and float).

 Java uses + for addition and for string catenation.

 Some are potential trouble (e.g., & in C and C++)

Expressions and Assignment Statements

Operator overloading happens when the same operator (like +, &, *, etc.) is used for different purposes
depending on the context.

The + operator:
•In Java, the + operator is used both for addition and for string concatenation.

The & operator in C and C++:


•In C and C++, the & operator can have different meanings:
• Bitwise AND: x & y → Performs bitwise AND between x and y.
• Address-of operator: &x → Gives the memory address of x.
•This dual meaning can be confusing if you're not sure which version of & you're dealing with.

23
Overloaded Operators

– Causes the address of y to be placed in x.

– Some loss of readability to use the same symbol for two completely
unrelated operations.

– The simple keying error of leaving out the first operand for a bitwise AND
operation can go undetected by the compiler “difficult to diagnose”.

Expressions and Assignment Statements

In C and C++, the & operator has two very different uses, which can cause confusion:

Address-of operator (&):


•When you use the & before a variable, it gives you the memory address of that variable.
Bitwise AND operator (&):
•When you use the & between two variables, it performs a bitwise AND operation.

24
Overloaded Operators

 C++, C#, and F# allow user-defined overloaded operators


– When sensibly used, such operators can be an aid to readability (avoid
method calls, expressions appear natural)
– Potential problems:

• Users can define nonsense operations


• Readability may suffer, even when the operators make sense

Expressions and Assignment Statements

C++, C#, and F# are programming languages that allow programmers to define their own behavior for operators
(like +, -, *, etc.) when applied to custom types (such as classes or structs). This process is called operator
overloading. For example, you can define how the + operator should behave when used with objects of a class you
created.

"When sensibly used, such operators can be an aid to readability (avoid method calls, expressions appear
natural)."
If operator overloading is used correctly, it can make code easier to read. Instead of calling a method like
object.add(otherObject), you can simply use an operator like object + otherObject. This makes the code look more
natural and similar to how we write regular arithmetic expressions, improving readability and clarity.

"Readability may suffer, even when the operators make sense."


Even if the operator overloading is logically correct, it could still make the code harder to understand. If you see a
line like time1 + time2, you might wonder: “What exactly does this mean?” For someone unfamiliar with the code,
even though + is correctly overloaded to add two times together, it can be less intuitive than using a function
name like addTime().

25
Activity – Essay
1. Programming languages have rules about which
operations happen first (like multiplication before
addition). Do you think these rules make
programming easier, or would it be better if it was
more "what you see is what you get"?

2. When we write an expression, the computer


fetches numbers from memory and does the math.
Do you think programmers should know about these
"behind-the-scenes" steps, or is it okay to just focus
on the result?

26
Type Conversions

 A narrowing conversion is one that converts an object to a type that


cannot include all of the values of the original type e.g., double to float.

 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
e.g., int to float.

 Coercion in Expressions
– 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

Expressions and Assignment Statements

"A narrowing conversion is one that converts an object to a type that cannot include all of the values of the
original type e.g., double to float."
A narrowing conversion happens when you convert a value to a type that cannot represent all the values of the
original type. This usually happens when you are trying to fit a larger type into a smaller type, which might cause
loss of information.

"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 e.g., int to float."
A widening conversion is the opposite of narrowing. It happens when you convert a value to a type that can hold
at least all the values from the original type, or at least close approximations of them. This type of conversion
increases the range of values.

• Coercion is the process of automatically converting a value from one type to another
• In the expression 5 + 3.2, 5 is an int and 3.2 is a float, so this is a mixed-mode expression.
• Coercion refers to an implicit type conversion, meaning the compiler or interpreter automatically converts
one type to another in situations where necessary, without the programmer’s explicit request.

27
Type Conversions

– In most languages, all numeric types are coerced in expressions, using


widening conversions

– In ML and F#, there are no coercions in expressions

Expressions and Assignment Statements

"In most languages, all numeric types are coerced in expressions, using widening conversions."
In most programming languages, when you have expressions involving numbers of different types (like int, float,
double), the language automatically converts the smaller types into the larger ones (widening conversions). This
ensures that the expression can work correctly even if the numbers are of different types.

"In ML and F#, there are no coercions in expressions."


Some programming languages, like ML and F#, do not allow automatic type coercion in expressions. If you try to
use operands of different types, the compiler will require you to explicitly convert them yourself rather than doing
it automatically.

28
Type Conversions

– Language designers are not in agreement on the issue of coercions in


arithmetic expressions
• Those against a broad range of coercions are concerned with the
reliability problems that can result from such coercions, because they
eliminate the benefits of type checking
• Those who would rather include a wide range of coercions are more
concerned with the loss in flexibility that results from restrictions.
• The issue is whether programmers should be concerned with this
category of errors or whether the compiler should detect them.

Expressions and Assignment Statements

3. "Language designers are not in agreement on the issue of coercions in arithmetic expressions."
The choice of whether to allow automatic coercion in arithmetic expressions is a debated issue among language designers. Some prefer it, while others don't, and there are
valid concerns on both sides. There isn't a universal agreement on the best approach.
4. "Those against a broad range of coercions are concerned with the reliability problems that can result from such coercions, because they eliminate the benefits of type
checking."
Some programmers and language designers oppose broad coercions (automatic type conversions) because they believe it can lead to reliability issues. If the compiler
automatically converts types in ways that might not be obvious, it can cause bugs or unexpected behavior that are hard to detect. This also undermines the benefits of
type checking, which is supposed to catch type-related errors.
• Example:
If a language automatically converts an integer to a float in an operation like 5 + "3.2", you might end up with a result that's not what you expected. The
problem is that you didn't explicitly tell the language how to handle this conversion, and the error might slip through unnoticed.
5. "Those who would rather include a wide range of coercions are more concerned with the loss in flexibility that results from restrictions."
On the other hand, some language designers favor including more coercions because they think that restricting them too much can reduce flexibility in programming. With
more automatic conversions, programmers can write more concise and flexible code without having to worry about explicitly converting types every time they mix different
types in expressions.
• Example:
If you want to add an int and a float, having automatic coercion means you don’t have to manually convert the int to a float each time. This can make the
code more flexible and easier to write, especially in complex calculations.
6. "The issue is whether programmers should be concerned with this category of errors or whether the compiler should detect them."
The core debate revolves around whether programmers should actively manage the potential errors that come from type coercion (by explicitly converting types) or if the
compiler should take care of it automatically, allowing the programmer to focus on the logic of the program without worrying about every little detail of type conversion.
• Example:
Should the programmer manually check and convert types like int to float when needed, or should the compiler just handle it automatically and report
errors if something goes wrong?

29
Type Conversions

– Ex: Java

int a;
float b, c, d;
...
d = b * a;

• Assume that the second operand of the multiplication operator was


supposed to be c, but because of a keying error it wat typed as a

• Because mixed-mode expressions are legal in Java, the compiler would not
detect this as an error. Simply, b will be coerced to float.

Expressions and Assignment Statements

30
Explicit Type Conversions

 In the C-based languages, explicit type conversions are called casts

 Ex: In Java, to specify a cast, the desired type is placed in parentheses just
before the expression to be converted, as in

(int)angle

Expressions and Assignment Statements

31
Relational Expressions

 A relational operator: an operator that compares the values of its two


operands

 Relational Expressions: two operands and one relational operator

 The value of a relational expression is Boolean, unless it is not a type


included in the language
– Use relational operators and operands of various types
– Operator symbols used vary somewhat among languages (!=, /=, .NE.,
<>, #)

Expressions and Assignment Statements

"A relational operator: an operator that compares the values of its two operands."
•Explanation:
A relational operator is used to compare two values. The result of this comparison is usually a true or false value (Boolean), depending on
whether the comparison is valid or not. These operators typically check for relationships like equality, inequality, greater than, less than,
etc.
• Examples of relational operators:
• == (equal to)
• != (not equal to)
• < (less than)
• > (greater than)
• <= (less than or equal to)
• >= (greater than or equal to)
"Operator symbols used vary somewhat among languages (!=, /=, .NE., <>, #)"
•Explanation:
The symbols for relational operators can vary between different programming languages. While some languages use standard symbols
like != for "not equal to" or == for "equal to," others may use different representations.
• Example:
• != (not equal to) in languages like C, Java, and Python
• /= (not equal to) in languages like Python and Pascal
• .NE. (not equal to) in languages like Fortran
• <> (not equal to) in languages like SQL and older versions of Visual Basic
• # (not equal to) in some variants of assembly language

32
Relational and Boolean Expressions

 The syntax of the relational operators available in some common


languages is as follows:

Expressions and Assignment Statements

33
Relational and Boolean Expressions

 JavaScript and PHP have two additional relational operator, === and !==
– Similar to their cousins, == and !=, except that they do not coerce their
operands

Expressions and Assignment Statements

34
Boolean Expressions

 Operands are Boolean and the result is Boolean

Expressions and Assignment Statements

35
Boolean Expressions

 Versions of C prior to C99 have 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

 a>b>c

– The left most operator is evaluated first because the relational


operators of C are left associative, producing either 0 or 1
– Then, this result is compared with var c. There is never a comparison
between b and c.

Expressions and Assignment Statements

36
Short-Circuit Evaluation

 A short-circuit evaluation of an expression is one in which the result is


determined without evaluating all of the operands and/or operators.

 Ex:

(13 * a) * (b/13 – 1)

// is independent of the value of (b/13 – 1) if a = 0, because 0 * x = 0 for any x

– So when a = 0, there is no need to evaluate (b/13 – 1) or perform the


second multiplication.
– However, this shortcut is not easily detected during execution, so it is
never taken.

Expressions and Assignment Statements

Short-circuit evaluation is a technique where the evaluation of an expression stops as soon as the result is
determined.

A short-circuit evaluation occurs when the program can determine the result of an expression early, without
evaluating all parts of the expression. This can happen when the result of a certain part of the expression is enough
to determine the overall result, and further evaluation becomes unnecessary.

EX: In an OR (||) expression, if the first operand is true, then the whole expression will be true regardless of the
second operand. So, the second operand isn't evaluated (this is short-circuiting).

37
Short-Circuit Evaluation

 The value of the Boolean expression:

(a >= 0) && (b < 10)

// is independent of the second expression if a < 0, because expression (FALSE


&& (b < 10)) is FALSE for all values of b

– So when a < 0, there is no need to evaluate b, the constant 10, the


second relational expression, or the && operation.
– Unlike the case of arithmetic expressions, this shortcut can be easily
discovered during execution.

Expressions and Assignment Statements

•If a < 0, then the first part of the expression, (a >= 0), becomes false.
• In a logical AND expression, if the first operand is false, the entire expression will always be false,
regardless of the value of the second operand.
• So, when a < 0, the value of the second expression (b < 10) doesn't matter because the whole
expression is already determined to be false.

38
Assignment Statements

Simple Assignments

 The C-based languages use == as the equality relational operator to avoid


confusion with their assignment operator

 The operator symbol for assignment:


1. = Fortran, Basic, PL/I, C, C++, Java
2. := ALGOL, Pascal, Ada

Expressions and Assignment Statements

"The C-based languages use == as the equality relational operator to avoid confusion with their assignment
operator“

In C-based languages (like C, C++, Java), the equality operator is == (double equals). This is different from the
assignment operator =.
• The reason for this distinction is to avoid confusion between the two operations.
• == is used to compare two values (e.g., a == b checks if a is equal to b).
• = is used to assign a value to a variable (e.g., a = 5 assigns the value 5 to a).
•This distinction is crucial because using the wrong operator (e.g., using = instead of ==) would lead to logical errors
in the program.

39
Assignment Statements

Conditional Targets

 Ex: Perl

Expressions and Assignment Statements

In programming, conditional targets typically refer to the concept where the result of an expression or operation
depends on a condition, and the action or value chosen is determined by that condition.

In Perl, conditional targets often relate to how the language handles conditional statements and expressions to
determine which block of code should be executed.

Perl has a variety of ways to handle conditional logic, including if, elsif, and else constructs. Additionally, Perl
supports conditional expressions like the ternary operator (?:), which is used to assign values based on a condition.

40
Assignment Statements

Compound Assignment Operators

 A compound assignment operator is a shorthand method of specifying a


commonly needed form of assignment
 The form of assignment that can be abbreviated with this technique has
the destination variable also appearing as the first operand in the
expression on the right side, as in

a=a+b

 The syntax of assignment operators that is the catenation of the desired


binary operator to the = operator

sum += value; ⇔ sum = sum + value;

Expressions and Assignment Statements

A compound assignment operator is a shorthand way of writing expressions that involve the destination variable
being used on both sides of an assignment. The idea is to make the code more concise and readable.

•The basic form of a compound assignment operator combines a binary operation with the assignment operator
(=). It allows you to perform the operation and assign the result to the same variable in one step.

•Instead of writing the full expression like a = a + b, you can use a shorthand version like a += b, which saves space
and improves readability.

41
Assignment Statements

Unary Assignment Operators

 C-based languages include that are actually abbreviated assignments two


special unary operators
 They combine increment and decrement operations with assignments
 The operators ++ and -- can be used either in expression or to form stand-
alone singleoperator assignment statements. They can appear as prefix
operators:

sum = ++ count; ⇔ count = count + 1; sum = count;

 If the same operator is used as a postfix operator:

sum = count ++; ⇔ sum = count; count = count + 1;

Expressions and Assignment Statements

A unary operator is called so because it operates on only one operand. The term "unary" comes from the Latin
word "unus," meaning one. In programming, unary operators take a single value or operand, modify it, and return a
result.

In C-based languages, there are two special unary operators used for incrementing and decrementing a variable’s
value, which can be combined with assignment operations.

These operators are ++ (increment) and -- (decrement), and they provide a shorthand way of updating a variable's
value in a single operation.

. Increment Operator (++)


The ++ operator adds 1 to the value of a variable.

Decrement Operator (--)


Similarly, the -- operator subtracts 1 from the value of a variable.

42
Assignment Statements

Assignment as an Expression

 This design treats the assignment operator much like any other binary
operator, except that it has the side effect of changing its left operand.

 Ex:

int a, b, c;
a = 5; // Assignment
b = (c = 10) + 2; // Assignment as part of an expression

Expressions and Assignment Statements

Assignment as an Expression is a programming design approach where the assignment operator (=) is treated like
a regular binary operator. In this design, the assignment not only updates the value of the left operand but also
returns a value (usually the value assigned). This means that an assignment can be used as part of a larger
expression, allowing it to participate in computations or be chained with other operations.

(c = 10): The value 10 is assigned to c. Since the assignment operator returns the value being assigned, (c = 10)
evaluates to 10.
(c = 10) + 2: After assigning 10 to c, the expression becomes 10 + 2, which evaluates to 12.
b = 12: Finally, the value 12 is assigned to b.

43
Assignment Statements

Assignment as an Expression

 Disadvantage: another kind of expression side effect which leads to


expressions that are difficult to read and understand.
 For example:

Expressions and Assignment Statements

44
Assignment Statements

Assignment as an Expression

 There is a loss of error detection in the C design of the assignment


operation that frequently leads to program errors

Expressions and Assignment Statements

in C, you can use the assignment operator (=) not just to assign a value to a variable, but also as part of a larger
expression.

If ( x = y )

Instead of checking if x is equal to y, it assigns y to x, and the condition will always be true, which might not be
what the programmer intended.

45
Assignment Statements

Multiple Assignments

 Perl, Ruby, and Lua provide multiple-target multiple-source assignments

 Ex: Perl

($first, $second, $third) = (20, 30, 40);

Expressions and Assignment Statements

46
Assignment Statements

Assignment in Functional Programming Languages

 Identifiers in functional languages are only names of values

 Ex: in ML, names are bound to values with the val declaration, whose form
is exemplified in the following:

val cost = quantity * price;

– If cost appears on the left side of a subsequent val declaration, that


declaration creates a new version of the name cost, which has no
relationship with the previous version, which is then hidden

Expressions and Assignment Statements

In functional programming languages, assignment is handled differently than in imperative languages (like C or
Java).

Identifiers as Names of Values


In functional programming, variables (or identifiers) don't store mutable values as they do in imperative languages.
Instead, they bind to values. This means that once a variable is set to a value, it cannot be changed or reassigned
later in the program. The variable essentially "represents" that value for the rest of the program.

val cost = quantity * price;


cost is a name that refers to the result of multiplying quantity and price.
The value of cost cannot change after this assignment.

New Bindings Hide Old Ones


If you declare a new variable with the same name in a later expression or scope, it hides the earlier binding of that
variable. The earlier variable's value is still remembered, but it is not accessible in the current scope.
EX: val cost = 100;
val cost = 200;

47
Mixed-Mode Assignment

 Assignment statements can also be mixed-mode

 In Fortran, C, and C++, any numeric value can be assigned to any


numeric scalar variable; whatever conversion is necessary is done.

 In Java and C#, only widening assignment coercions are done.

 In Ada, there is no assignment coercion.

Expressions and Assignment Statements

Mixed-Mode Assignment
A mixed-mode assignment occurs when the value being assigned to a variable is of a different type than the variable itself. In this case,
the language may automatically convert or coerce the value to the correct type before the assignment is made.
For example:
•You might assign an integer value to a floating-point variable (e.g., int to float).
•Or assign a larger numeric type to a smaller one (e.g., double to int).
How Different Languages Handle Mixed-Mode Assignment
1.Fortran, C, and C++:
1. In these languages, you can assign any numeric value (like an integer, float, or double) to any numeric scalar variable (such
as a variable of type int, float, etc.).
2. The language automatically converts the value to the appropriate type for the target variable. This may involve narrowing
(e.g., converting from double to int) or widening (e.g., converting from int to float) conversions.
Java and C#:
•In Java and C#, only widening assignment coercions are allowed.
•This means that smaller types (e.g., int) can be assigned to larger types (e.g., float or double) without error, but the reverse (narrowing
conversion) requires explicit casting.
Ada:
•Ada is stricter about type safety and does not allow assignment coercion.
•This means you cannot automatically assign a value of one type to a variable of a different type, even if it’s numerically compatible. If you
need to assign a value of one type to another, you must use explicit type conversion (casting) functions.

48
Mixed-Mode Assignment

 In all languages that allow mixed-mode assignment, the coercion


takes place only after the right side expression has been evaluated.
For example, consider the following code:

int a, b; float c;
...
c = a / b;

– Because c is float, the values of a and b could be coerced to


float before the division, which could produce a different value
for c than if the coercion were delayed (for example, if a were 2
and b were 3).

Expressions and Assignment Statements

49
Summary

 Expressions consist of constants, variables, parentheses, function


calls, and operators
 Assignment statements include target variables, assignments
operators, and expressions
 The associativity and precedence rules for operators in the
expressions of a language determine the order of operator
evaluation in those expressions
 Operand evaluation order is important if functional side effects are
possible
 Type conversions can be widening or narrowing
– Some narrowing conversions produce erroneous values
– Implicit type conversions, or coercions, in expressions are
common, although they eliminate the error-detection benefit of
type checking, thus lowing reliability

Expressions and Assignment Statements

50
Thank you 

51

You might also like