Lecture 3: Imperative Programming.
* Basic Elements: Actions: Change the value of a variable
X:= e
The value of of e is assigned to X; the old value of
X is forgotten
*Directing the Flow of Control through a program
*Control + Data Structures + Procedures
-- Control Structures (Discussed already)
Structured Programming:
The structure of the program text should help us understand
what the program does
Specifically:
Structured Control Flow: A program is structured
if the flow of control through the program is evident from the syntactic structure of the program text
Example: GCL
-- Closing keywords
-- avoids problems due to misplaced keywords
-- Dangling else (matching an else with the nearest unmatched if)
-- use closing keywords.
-- use '' end '' to close the if statements
if expr1 then S1
else if expr2 then S2
else if expr3 then stmt3
else
s4
end
end
end
-- Avoid proliferation of keywords
if expr1 then S1
elseif expr2 then S2
elseif expr3 then stmt3
else
s4
end
EBNF Notation:
if expr then Stmt-list { elseif expr then SL} [else SL] end
end
end
end
Handling Special Cases in Loops:
Break: sends the control out of the enclosing loop to the
statement following the loop
Continue: repeats the enclosing loop by sending control to the
beginning of the loop
-- handle special case
while expr do
if special case then special-exec; break
endif
handle normal case
endwhile
** using Continue
while expr do
if normal case then normal-exec; continue
endif
Handle Special case.
endwhile
(Withe break - no longer one exit)
Return Statement:
return (expression)
-- send control back from from a procedure to the caller carrying the value.
if the return statement is not in a procedure, the program halts.
Example:
for i:=n downto 1 do
if x= A[i] then return i;
return 0;
(returning from a linear search)
Goto Statements: goto L
-- interrupts normal control flow
(gives no indication as to where L is)
L: Statement
-- could lead to unreadable programs
-- translators could introduce gotos for efficient translation -- exceptions etc.
DATA REPRESENTATION:
--- object, data object: refers to entities that are meaningful to an application
--- representation or data representation : organization of values in a program
VALUES and Their Types
Data Representations in imperative languages are built up from values that can be manipulated directly by the underlying machine
BASIC Values: Typically fit in machine locations
-- integers, characters, reals, booleans
-- first class citizens
-- denoted by a name, value of an expression, appear in the right hand side
of an assignment and so on.
-- operations on basic values are built into the language
-- languages support building structured types
Types: Classify representations
-- a type expression (type) describes how a data data representation is built up
Used:
-- represent data objects
-- layout values in the underlying machine
-- check that operators are applied properly within expressions
Basic types: boolean, char, integer, real
User defined Types : type =
Basic Types:
Enumerations:
type day = (Mon, tue,Wed,thu, fri,sat,sun)
type boolean (true, false)
-- ordinals ord(x) maps name x to its integer position in the
enumeration.
-- successor: succ(x)
-- Predecessor: pred(x)
Integers and Reals
Several operators
Short Circuit evaluation
C: || logical or
&& logical and
Subranges
Arrays: Sequences of Elements
Array layout
Efficient address computation
-- Base + value depending on indices
A: array [low..high] of integer
A[i] i*w + (base - low *w)
Multi Dimensional Arrays:
- Row major order
- column major order
Static and Dynamic Array Bounds
Array Values and Initialization
RECORDS:
Named Fields
-- operations on records
Arrays records
Component types homogeneous heterogeneous
Component selectors expr evaluated at run time names known at compile time
UNIONS and VARIANT RECORDS
SETS
POINTERS: Efficiency and Dynamic Allocation
Types and Error Checking
-- apply to values and expressions, usually studied in
expression-oriented/functional languages
-- type distinctions between values carry over to expressions
** extends the notion of types from values to variables, and
from variables to expressions
Variable Bindings: The Type of a variable
-- Language design determines whether a variable has a fixed type
-- C (Pascal) -- fixed
-- Lisp, Smalltalk do not restrict
Variable Binding: associates a property to a variable
-- binding is static (early bindings) if it happens before the program runs
-- dynamic (late bindings) if it happens at run time
Type Systems: the type of an expression
-- Design Principle: Every expression must have a type
-- is a set of rules for associating a type with expressions
-- rejects if a type is not associated with an expression
-- rules specify the proper usage of each operator in the language.
Basic Rules of Type Checking
When a function from a set A to a set B is applied to an element of set A, the result is an element of set B
Arithmetic operators
If E and F have type int then E+F has also type int
Overloading
-- + * are usually overloaded
E, F have type int then E+ F has int
E, F have real so is E+F
Coercion: Implicit Type Conversion
-- a conversion from one type to another inserted automatically by a PL.
2 * 2.3 is the same as 2.0 * 2.3
Polymorphism:
- has a parameterized type (generic type)
-- stacks, arrays ...
In C and PASCAL, these are possible only on built in types.
C++ supports -- templates
Type Names and Type equivalence
x,y: array [1..10] of integer;
z: array [1..10] of integer;
Pascal: x and y have same type
but z does not
In C, all have same type
Structural Equivalence:
-- a type name is structurally equivalent to itself
-- two types are structurally equivalent if they are formed by
applying the same type constructor to structurally equivalent types
-- After a type declaration, TYPE n =T, the type name n is equivalent to T
type S: array [1..10] of integer
type T: array [1..10] of integer
S and T are structurally equivalent
Forms of name Equivalence:
-- Pure name Equivalence
** A type name is equivalent to itself, but no constructed type is
equal to any other constructed type
-- Transitive name equivalence
-- a type is equivalent with itself and can be declared equivalent to
other types
type S = integer
T = S
U = integer
A,T, U are equivalent
-- Type expression equivalence
-- A type name is equivalent only to itself.
-- Two type expressions are equivalent if they are formed by
applying the same constructor to equivalent expressions
That is, expressions have to be identical
Recursive Types (or circular types)
type link = ^ cell;
type cell = record info:integer;
next: link;
end
**link and cell are defined circularly.
p: link
p^: cell
p^.next : link
P^.next^: cell
.....
Static: at compile time
Dynamic Checking: requires run time code: array bounds, variants, ...
-- operations are applied properly
-- prevent errors
-- a program that executes without type errors is said to be type safe.
-- Strong: if it accepts only safe expressions
-- weak other wise