Transcript Binding

Coverage
• Variables
• Type Checking
• Scope
• Referencing Environments
• Data Types
• Arithmetic Expressions
• Control Flow
• Stack and Subprograms
• Programming for Imperative Features
Imperative Languages
1
Introduction
• Imperative languages are based on the concept of Von Neumann
machines where memory is separated from Central Processing Unit
(CPU); data and programs are stored in the same memory.
• Instructions and data are piped from memory to CPU for further
processing.
• Von Neumann machines have general purpose registers and Arithmetic
Logic Unit (ALU).
• Instruction cycle proceeds by fetching the instruction, updating the
program counter and then executing the instruction.
• Direct Memory Access (DMA) provides transfer of data from or to
Input-Output (I/O) devices and to or from memory by stealing memory
cycles from CPU.
Imperative Languages
2
Variables
• Languages is said to be turing complete if it has integer
variables, integer values, integer operations, assignment
statements, statement sequences, conditionals and
branching statements
• Names or identifiers are used to refer to variables,
procedures, constants, etc
• User-defined Names or identifiers
− Length, Case sensitivity
• COBOL: maximum variable length is 30 characters
• FORTRAN 90 and ANSI C: maximum 31 characters
• Ada, C# and Java: There is no limit on the length
• C++: no limit, but implementers often impose one
• C, C+ and Java: Case sensitive in nature
Imperative Languages
3
Variables
• Pascal and C: Variables are to be declared before use
• The name of a variable is used to identify and refer to the variable.
• Scope of a variable is the segment of the program within which it is
defined.
• Visibility of a variable is visible within some sub-segment if it can be
directly accessed using its name.
• Lifetime of a variable is the time period from the allocation of
memory to the variable to when the memory is de-allocated, during
program execution.
• Lifetime is a dynamic property while scope and visibility are static
properties
• Address is the memory location associated with the variable and it is
called as l-value (left value or locator value)
• Value (called as r-value or right value) is the actual contents of the
memory location of the variable
Imperative Languages
4
Variables
• Type of the variables controls the range of values and the set of
operations that could be performed
• The byte data type in Java is of one byte with values ranging from 128 to 127; short data type in Java is of two bytes with data ranging
from -32768 to 32767
• The process of associating an attribute to an entity is called as
Binding. The process of associating an operation and a symbol is also
called as Binding.
• Language design time:
− Also called Language definition time
− Programmer is given a definite set of syntax and program
structures
− Example: Operators with their respective operations, data types, …
− In C language, new data types can be defined, ex., struct.
Imperative Languages
5
Binding Time
•
•
•
•
Language implementation time:
− Binding might vary among different implementations of the same
language
− Depends on hardware architecture and operating system
− Floating point data type representation
Compile time:
− Also called as Translation time binding
− Binding of variables to its type in C or Java
− Allocation of memory for arrays or relative memory allocations
Load time:
− Also called Link time
− Binding the variables to the memory cell during loading time as in static
variables of C language and Fortran 77 variables
− Task is handled by loader or linker
Runtime:
− Also called Execution time binding
− Binding non-static variable to the respective memory cell is done at
runtime
− Binding of formal to actual parameters needs to be done at runtime
Imperative Languages
6
Variable Binding
• The process of binding a variable during compile time or load time or
at the beginning of runtime is called early binding.
• If the binding happens during later stages of the runtime, then it is
called late binding.
• In C#:
− Generic data type Object is bounded using late binding while a
specific object type is bounded using early binding
• Static binding occurs before run time and remains unchanged
throughout program execution
• Dynamic binding occurs during execution or can change during the
execution of the program
• JavaScript and PHP use dynamic binding
Imperative Languages
7
Variable Binding
• Dynamic binding example in JavaScript
− <script type="text/JavaScript">
− var myList = [1,2,3];
− document.write("myList[0] = " + myList[0]+ " "); // 1
− var myInteger = 45;
− document.write("myInteger[0] = " + myInteger[0]+ " "); // undefined
− document.write("myInteger = " + myInteger+ " "); // 45
− myList = myInteger; // List is overwritten by the integer element
− document.write("myList[0] = " + myList[0]+ " "); // undefined
− document.write("myList = " + myList+ " "); // 45
− var myArray = new Array();
− myArray[0]="India";
− myArray[1]="Brunei Darussalam";
− myList = myArray; // List overwritten by the array elements.
− document.write("myList[0] = " + myList[0]+ " "); // India
− document.write("<BR>");
− </script>
• Doing something similar in C or C++ or Java will generate an error.
Imperative Languages
8
Variables
•
•
•
Type inferencing
− Type of the variable is based on the context of the reference and not by
the assignment statement
− Used in ML, Miranda and Haskell
Variable type declaration
− Explicit: Specified with a statement
− Implicit: Inferred from the first assignment
• Example: FORTRAN, PL/I, BASIC and Perl
Lifetime of a variable
− Static:
• Variable is bound to a memory cell before execution and it remains
bounded to the same memory variable throughout execution
• Example: Fortran 77 variables, C or C# static variables
− Stack-dynamic:
• Variable is bound to a memory cell during the process of elaboration
of the declaration of the variable.
• This process happens during program execution
• Example: local variables in C subprogram and Java methods
• Variables defined in methods of Java or C++ or C# are by default
stack-dynamic.
Imperative Languages
9
Lifetime of a variable
•
Lifetime of a variable
− Explicit heap-dynamic:
• Allocation and de-allocation are done explicitly using certain
directives from the programmer.
• They are referenced through pointers or references
• Example: all objects in Java and dynamic objects created in
C++ using new and delete methods
• In C#, objects defined using class keyword are allocated on
the heap but those defined using struct keyword are stack
allocated.
− Implicit heap-dynamic:
• Allocation and de-allocation is caused by assignment
statements
• Example: all variables in APL (A Programming Language), all
strings and arrays in Perl and JavaScript.
Imperative Languages
10
Pointer variable
• Pointers are used to refer to memory locations where variables are
stored
• Used in Pascal [called as dynamic variables, referred using ^ operator],
C, C++, C# [with unsafe], etc
• In C: & is used to refer to memory location and * is used to refer to the
contents of the memory location
• In C, void * is a generic pointer. Generic pointer cannot be
dereferenced and thus pointer arithmetic operations can not be
applied on them
Imperative Languages
11
Pointer variable
12
•
•
•
•
•
#include <stdio.h>
int main()
{
int a = 5; int b = 10;
int *ptra = &a; // ptra is a pointer to a
•
•
•
•
int *ptrb = &b; // ptrb is a pointer to b
*ptra = *ptrb; // a and b will have the same value
printf("*ptra = %d, *ptrb = %d\n", *ptra, *ptrb);
printf("a = %d, b = %d\n", a, b);
•
•
•
•
•
if (ptra == ptrb) printf("%s", "ptra and ptrb are the same\n");
else printf("%s", "ptra and ptrb are not the same\n");
if (*ptra == *ptrb) printf("%s", "*ptra and *ptrb are the same\n");
ptra = ptrb;
// pointers now point only to b
printf("a = %d, b = %d\n", a, b);
5
ptra
a
10
ptrb
b
After the statement:
ptra = ptrb;
ptra
• Return 0;
• }
5
a
10
ptrb
Imperative Languages
b
Type Checking
13
• Make sure that the operands and the operator are of compatible types
• Errors detected during type checking are called as type errors
• Process of conversion of one type to another by the compiler itself is
called as coercion
• If all type bindings are static, nearly all type checking can be static. If
type bindings are dynamic, then type checking must also be dynamic.
• A language which could catch all type errors is called strongly typed
language.
Imperative Languages
Type Checking
14
• Holding different values at different times
− Pascal: variant records
− C or C++: union inside struct
• In C and C++, parameter type checking can be avoided and unions are
not type checked
• Ada and Java are almost strongly typed languages
Imperative Languages
Type Checking
15
• ML and Haskell are strongly typed languages
• Fortran 77, Pascal, C and C++ are not considered as strongly typed
languages
• Languages that are without static type systems are called as untyped
languages or dynamically typed languages
− Example: Scheme, Smalltalk, Perl, …
• Static or Translation-time Type Checking
− Checking for type errors at translation stage
− Will indicate type errors earlier
• Attaching types to expressions is called as type inferencing
−
−
−
−
int main( ) { float value; value = 10/3;
printf("%f\n",value); return 0; }
This program returns 3.000000.
To get 3.333333, we need to use 10.0/3 or 10/3.0
Imperative Languages
Type Equivalence
•
Type restrictions on structured types
−
−
−
−
•
In Pascal, formal parameters (parameter present in the subprogram) must
be of the same type as their corresponding actual parameters (parameter
present in the subprogram call).
In Pascal, Subranges, which has a limited range of allowed values of
integer types, is not compatible with integer types
For example, a range 10 ... 12 is a subrange of integer type
Subrange type is not present in C++ or Java.
Structure type compatibility or structure equivalence
−
−
−
−
Equal only if they have identical structures
Two records having the same structure but different field names should be
considered compatible or not.
Two array having the same type but different subscript should be
considered compatible or not.
Two enumerations with their components spelled differently should be
considered compatible or not.
Imperative Languages
16
Type Equivalence
•
C language: Following two arrays are structurally equivalent.
−
−
•
Same size and same content
int a[3] = {1,2,3}; int b[3] = {1,2,3};
Name equivalence:
−
Needs to be of same name
•
C language: struct does not imply structure equivalent
•
struct x { int a; }; struct y { int a; };
•
typedef struct {int x1; char z;} Rec1; typedef Rec1 Rec2;
•
typedef struct {int x2; char z;} Rec3;
•
int main() { struct x z, a2; struct y a1;
•
z = a2; z = a1; // z = a2 has no error but z = a1 has compile error
•
Rec1 a, b; Rec2 c; Rec3 d; a = b; // Name equivalence
•
a = c; // Name equivalence
•
// a = d; // Generates compilation error. }
Imperative Languages
17
Type Equivalence
•
Declaration equivalence
−
−
−
−
•
Must have the same original structure if traced backwards
a and b are considered declaration equivalent.
int a[10], b[10];
typedef char * string; string a; char *b;
Pascal
−
−
Parameter type checking is using Name Equivalence
Other types check is upto the implementation
Imperative Languages
18
Type Equivalence
•
C or C++:
−
•
Supports structured type compatibility except for records or struct
Java:
−
Does not support structure equivalent in classes.
• class C1 { int x, y; }
• class C2 { int x, y; }
• public class Equivalence
• {public static void main(String[] args)
•
{ C1 a = new C1(); C1 c = new C1();
•
a = c; // works ok.
•
C2 b = new C2();
•
a = b; // Compilation error - incompatible.
•
C1 z = new C2(); // Compilation error.
•
}
• }
Imperative Languages
19
Scope
•
Scope of any variable is the range of statements over which it is
visible
−
•
Depends on the location of the declaration of the variable
Local variables override global variables
Handled during translation or compile time itself
Dynamic Scope:
−
−
•
Lexical scope: Depends on where the variable is defined.
Static Scope
−
−
−
•
20
Based on the flow of execution of the program
Dynamic scope makes the reference convenient but readability is
affected.
Scope and lifetime are sometimes closely related but are different
concepts
Imperative Languages
Scope
•
What is the output of this C program?
−
x is printed as 110 as static scope is used.
Imperative Languages
21
Referencing Environments
•
Referencing environment of a statement indicates the collection of all
names that are visible in the statement
−
−
•
22
Static-scoped language: local variables and visible variables of the
enclosing scopes
Dynamic-scoped languages: local variables and visible variables of
all active subprograms
Components of referencing environment:
−
−
Local referencing environment:
• Called as local environment
• Formal parameters, local variables and subprograms that are
defined as part of current subprogram
Global referencing environment:
• Global associations that are available during the current
execution
Imperative Languages
Referencing Environments
•
Components of referencing environment:
−
−
•
23
Non-local referencing environment:
• Associations that are not created on entry into subprogram
Predefined referencing environment:
• Associations defined in the language definition itself
Named constant:
−
−
Value is bound to the variable only when the storage is bounded
Can be done statically (called as manifest constants) or
dynamically
− Pascal has literals only
− Fortran 90 has constant-valued expression where all terms are
either literal or named constants;
− Ada and C++ allow named constants to be dynamically bounded to
values.
• // C++ named constant dynamically bounded.
• const int area = side * side;
Imperative Languages
Referencing Environments
• Java has named constants dynamically bounded, with an additional
reserved word final.
• class Constants { public static void main(String[] args)
•
{ int side = 20; final int length = 20; final int area = side * side;
•
System.out.println(length); // Prints 20
•
System.out.println(area); // Prints 400
•
} }
• In C#, there are two types of named constants: const and readonly.
− Const-named constants have value assigned at compile time and
can not be changed once established
− Readonly-named constants have value assigned at run time and can
not changed once established
− Readonly-named constants can be assigned in a constructor but
const-named constants can not be assigned in a constructor
Imperative Languages
24
Referencing Environments
• In C#, there are two types of named constants: const and readonly.
− Readonly is an access privilege where the value can be changed
from the owner but not from outside.
• const double PI = 3.14159;
• readonly double PI = 3.14159;
•
Binding of a variable to a value at the time it is bound to the storage
is called initialization. Initialization is mostly done during the
declaration statement.
− For example, in Java, int sum = 0;
Imperative Languages
25
Data Types
• Various data types: primitive data types, character string types, userdefined ordinal types, array types, associative arrays, record types,
union types and pointer types
• Primitive Data Types
− Not represented or defined in terms of any other data type
− Called as Scalar Structure as only one occurrence of data type is
held at any time
− Integer: signed or unsigned; byte, short, int, long
− Floating point: IEEE 754 Floating Point representation
• Represented using sign, exponent and mantissa
• C language: float (32 bits), double (64 bits)
− Decimal: Numbers with fixed digits like money, cost, etc
− Boolean: bits represented as bytes
− Character: numeric codes like ASCII or Unicode
Imperative Languages
26
Data Types
• C language does not have Boolean data type:
− typedef enum {false, true} bool;
− int main()
− { int i = 10; typedef enum {false, true} bool; bool bv;
−
bv = i + 20;
−
printf("Integer Value = %d\nBoolean Value = %d\n", i, bv);
−
return 0; }
− The boolean variable bv is stored with an integer number 30.
Imperative Languages
27
Boolean Data Type
• C++ language with bool data type:
− Non-zero (including negative values) represent true and zero
represents false
• #include <iostream>
// iostream.h is depreciated
• using namespace std;
// needed for cout to work
• // if namespace std is not used, cout must be represented as std::cout
• // similarly, all functions should be with respective namespace
• int main()
• { int i = 10; bool bv = true; cout << bv << endl;
•
bv = i + 20; cout << bv << endl; return 0; }
• This program returns the binary value as 1, even after the assignment
statement. This is because C++ considers any non-zero value as 1.
• In C#, assigning an integer value to bool variable gives an error. It
should be assigned as: bool variablename = true;
Imperative Languages
28
String Data Type
• Sequence of characters and so a non-scalar structure
• C language: String is considered as a character array
−
−
−
−
−
−
−
−
−
−
#include <stdio.h>
int main()
{
char x[10];
// x[0] = "H"; // No compilation error, but nothing is printed.
// Usage of double-quotes is wrong.
x[0] = 'H'; x[1] = 'e';
x[2] = '\0'; printf("%s\n",x);
return 0;
}
Imperative Languages
29
User-defined Ordinal Types
• Ordinal types are of a set provided in a discrete order
• Discrete order is of first element, last element and the presence of
previous and next elements
• Enumeration type
− Consists of all possible values that are considered as symbolic
constants
− C or C++ language:
• enum Name {Sat, Sun, Mon, Tue, Wed, Thu, Fri};
• enum Name x = Sat; // x is the variable
• Name x; // x is the variable – Not allowed in C
• x++; // Allowed in C but not in C++
• int a = Sat; printf("%d\n",a); // Allowed in C and C++
• // this is equivalent to #define Zero 0; #define One 1
• enum {Zero, One}; printf("%d\n",Zero}; // Prints 0
• C# language: public enum Days {Mon, Tue, Wed, Thu, Fri, Sat, Sun};
Imperative Languages
30
User-defined Ordinal Types
• Subrange type
− Users should provide the ordered contiguous subsequence of an
ordinal type.
− In Pascal: type Month = 1 .. 12;
Imperative Languages
31
Arrays
• Collection of homogeneous data elements, positioned relative to the
first element
• Called as homogeneous structures
• If the array index crosses the boundary of the array, an array boundary
error occurs. Exception to this is COBOL language.
• Issues in handling arrays:
− What types are considered legal subscripts?
− If the subscript is represented as an expression, are they checked
for range?
− When does the language allocate space for the array?
− How many subscripts are allowed for an array?
− Is it a must to initialize the array objects?
− Can we allocate the subscript in two different ranges?
Imperative Languages
32
Arrays
• Types of Arrays:
− Static Array:
• Storage allocation is static and subscript range is statically
bounded
• No allocation or de-allocation of locations during runtime.
− Fixed stack dynamic array: The range is statically bounded but
the allocation is done during execution.
− Stack-dynamic array: Allocation is dynamic and subscript range is
also dynamically bound. But, once the range is fixed, it stays as it
is.
− Fixed heap-dynamic array: Subscript range is dynamic and
allocation is also dynamic but once they are bounded, they stay as
it is.
− Heap-dynamic array: Subscript range and allocation are dynamic
and changes could be done any number of times during the lifetime
of the array.
Imperative Languages
33
Arrays
• Arrays declared as static in C or C++ functions are static arrays
• Arrays not declared as static in C or C++ functions are fixed stackdynamic arrays
• Arrays in Ada language are stack dynamic
• Arrays in Java are fixed heap dynamic arrays
• Heap-dynamic arrays could be created in C# using the class ArrayList.
• With regards to array initialization:
− Perl does it as: @a = (1..12);
− C and C++ language: int group [] = {1,2,3,4,6};
− C# language: int[] group = new int[]{1,2,3,4,6};
Imperative Languages
34
Arrays
• Array slicing: Slice is some substructure of an array. It could be used if
there are certain operations to be performed on a part of the array.
− In Perl, @_ is the list of incoming parameters to a sub.
− sub sortArray {
−
# @_ stands for the parameter passed to the sub.
−
my $n = @_ - 1;
−
@_[0..$n] = sort(@_[0..$n]);
− }
•
• C and Java have array index starting with 0
• Unlike C, Java allows the size of the array to be specified dynamically
because it is dynamically heap allocated
• Once the array size is specified, the size cannot be changed in Java.
Imperative Languages
35
Associative Array
• Unordered collection of data elements that are indexed by an equal
number of values called keys
• In Perl, names begin with % and literals are delimited by parenthesis.
− %hi_temps=("Monday"=>1,"Tuesday"=>2,…);
• Subscripting is done using braces and keys
− $hi_temps{"Wednesday"} = 3;
• Elements can be removed with delete
− delete $hi_temps{"Tuesday"};
Imperative Languages
36
Associative Array
• Associative arrays can be implemented in C++ as:
• #include <string>
• #include <map>
• #include <iostream>
• int main()
• { // studentrecord is a map from string to int
•
std::map<std::string, int> studentrecord;
•
studentrecord["Hazwan"] = 11;
// Hazwan's ID is 11
•
studentrecord ["Atul"] = 12;
// Atul's ID is 12
•
std::cout << "Atul's ID is " << studentrecord["Atul"] << std::endl;
• }
Imperative Languages
37
Records and Unions
• Record is a heterogeneous aggregate of data elements in which each
individual element is identified by its name.
− C++ struct is an example of records
• Union is similar to record by grouping heterogeneous elements but only
one value is stored at a time
• In C++, union within struct definition is called as anonymous union.
• Java does not possess both records and unions.
• Ada has a safe union mechanism called variant record where the
discriminant (which gives the type of data being stored) and the actual
value are stored at the same time
• Example when different information is stored at different time:
− For a train travel, the speed is applicable only when the train is
travelling between stations. But when the train stops at a station,
the speed element is not applicable
− Using arrays to store the information will waste spaces when speed
is not applicable
Imperative Languages
38
Records and Unions
• Pascal supports variant records, which could store different values of
different types at different times
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
program main(input,output);
type day = (weekday,weekend);
var employee : record
name : String; dept: String; salary: real;
case daytype : day of
weekday: (officephone : integer);
weekend: (housephone : integer; houseaddress : String);
end;
begin
employee.name:='Seyed Abdur Rahman'; employee.dept:='Language';
employee.salary:= 20000.00; employee.daytype:=weekday;
employee.officephone:= 23333; writeln(employee.name,' ',employee.dept);
writeln(employee.officephone); writeln(employee.salary:6:2);
{there should be no housephone because daytype=weekday}
// the value printed is same as officephone
writeln(employee.housephone);
employee.daytype:=weekend; employee.housephone:= 22222;
employee.houseaddress:='Mohideen Street, Kayalpatnam';
writeln(employee.housephone,' ',employee.houseaddress);
end.
Imperative Languages
39
Records and Unions
40
• Example in C language:
•
typedef union {
•
typedef struct { char *name; int id; uniondata details;
•
int marks; char grade; } uniondata;
int main() {
•
StudentRecord sturec;
•
sturec.name = "Noorul Haq";
•
sturec.details.marks = 84;
•
} StudentRecord;
sturec.id = 123456;
sturec.details.grade = 'X';
printf("Name = %s\n",sturec.name); printf("ID = %d\n",sturec.id);
•
printf("Marks="%d\n",sturec.details.marks);
•
printf("Marks=%c\n",sturec.details.grade);
•
return 0; }
• Output:
−
−
−
−
Name = Noorul Haq
ID = 123456
Marks=88
Grade=X
Imperative Languages
Arithmetic Expressions
• Arithmetic expression consists of operators, operands, parenthesis and
function calls
− Operator precedence rules:
• Describes how the expression is evaluated if adjacent operators
are of different precedence levels
• Typical precedence levels follow higher to lower precedence in
this order: Parenthesis, unary operators, **, * or / , + or − Operator associativity rules:
• Describes how the expression is evaluated if adjacent operators
are of same precedence level
• Typical associativity rules are: left to right except for ** which
is right to left
Imperative Languages
41
Arithmetic Expressions
42
− Order of operator evaluation:
• Typical evaluation order is: values of the variables are fetched;
constant values are fetched either from memory or from the
instruction itself; evaluate all operands and operators first,
with priority for parenthesized expressions; functional
references are handled.
• Functional site effects: Function might change the value of a
two-way parameter or a non-local variable
• To prevent these side effects, we do either of the following:
− Disallow functional side effects by having no two-way
parameters and no non-local variables in functions. This will
work but will prevent the flexibility of programming.
− Write language definition that the operand evaluation order
be fixed. This might create some impact on the compiler
optimizations.
Imperative Languages
Arithmetic Expressions
43
• Usage of user-defined operator overloading:
− One operator is used for more than one purpose
− + operator is used for both int and float types
− * operator is used for referencing pointers and multiplication in C
and C++
− Usage of overloaded operations might prevent compiler error
detection and reduce readability
− User-defined overload operators are allowed in C++ and Ada
− Java does not support user-defined operator overloading.
• Using mixed modes within expressions: Mixed mode expression is one
that has operands of different types.
• Restrictions on operand evaluation side effects.
• Arithmetic expressions could use unary operator that has one operand
or binary operator that has two operands or ternary operator that has
three operands.
Imperative Languages
Type Conversions
44
• Narrowing Conversion
− Converts an object to a type that cannot include all of the values
of the original type
− Example: float to int
• Widening Conversion
− Converts an object to a type that can include at least
approximations to all the values of the original type
− Example: int to float
• In mixed mode expressions, all numeric types are coerced in
expressions using widening conversions
• FORTRAN allows mixed mode arithmetic with real and integer data but
Pascal does not allow; Ada virtually has no coercions in expressions
• In C#, widening conversion is implicit; Java allows widening conversion
using type casting
• Explicit type conversions are called as casts (type casting)
− Example in Java: (int) speed /* Initially, speed is of float type */
Imperative Languages
Relational and Boolean Expressions
• C, C++, and Java have over 40 operators and at least 15 different
levels of precedence
• C does not have boolean data type
Imperative Languages
45
Input/Output
• FORTRAN uses READ and WRITE statements. There is no Stream I/O.
− READ(5,10) A,I
− 10 FORMAT(F5.3, I3)
• Where 5 in READ statement indicates the input device and 10 in READ
statement indicates the FORMAT statement
• F & I indicates the format of input as floating point and integer
respectively. The numbers 5.3 and 3 in FORMAT statement indicate the
number of digits used for representation.
• Concept of Stream I/O is used in Pascal.
− Input is viewed as a long stream of values that can occur virtually
anywhere in terms of spacing.
− Main concept of input is that it be ordered so that the appropriate
values show up for assignment to the corresponding input variables
Imperative Languages
46
Short-Circuit Evaluation
• While evaluating an expression, evaluation is stopped in the middle as
further evaluation won't change the value of the expression
• Ada programmers should choose one style (either full evaluation or
short circuit) for an entire program, using the other style (not chosen
style) only if necessary
• Languages like C, C++, C# and Java use short-circuit evaluation for the
usual Boolean operators (&& and ||), but also provide bitwise Boolean
operators that are not short circuited (& and |).
Imperative Languages
47
Assignment Statement
48
• Different symbols are used
− Fortran, Basic, PL/I, C, C++ and Java use =
− Algol, Pascal and Ada use :=
• Different assignments:
− In Perl, multiple target assignments can be done using
• ($a, $b) = (12, 13);
− In C, C++, C# and Java, conditional target setting can be done using
• total = (first == true) ? total : subtotal;
• If the condition (first == true) is true, then expression1 (total =
total) is evaluated. Else, expression2 (total = subtotal) will be
evaluated.
− Compound assignment operators are present in C, C++, C# and Java
as
• sum += next;
− Unary assignment operators are present in C, C++, C# and Java as
• b++;
Imperative Languages
Control Statements
• Different types:
− Selection statements like if, switch.
− Iterative statements like for, while, foreach.
− Unconditional branching like goto.
• Control Flow
− Composition:
• Execution is done one statement after another in sequence
• Statements can be grouped as compound statements
− begin … end OR { … }
− Selection or Alternation or Conditional Statements
• Only one of the given alternatives is evaluated
− Iteration
• Repeated few times without any condition
• Repeat only if the condition is satisfied
Imperative Languages
49
Control Statements
− Iteration
• Repeating based on a counter. Counter is incremented or
decremented
• Repeat based on data availability
• Indefinite repetition: while true
− Selection
• Choose between two or more paths
• Two-way selectors: if … then … else
− Fortran: IF (boolean_expr) statement
− The major drawback with this IF statement is that only one
statement could be selected. If we need more statements,
we need to use GOTO statement.
• Nested Selectors: if … if … else
− To which if does the else belongs to.
− C or Java: else is connected to the nearest if
Imperative Languages
50
Control Statements
− Selection
• Multiple-way selectors
− FORTRAN IF: IF (arithmetic exp) N1, N2, N3
• N1 is exp is –ve; N2 if exp is zero; N3 if exp is +ve
− FORTRAN has different GOTOs:
• Unconditional GOTO: GOTO n
• Computed GOTO: Based on a result of an expression
• Assigned GOTO: if ( x .gt. y) assign 6 to Label
− Case statement
• Type of exp allowed
• Segments can be single or compound statement
• Only one construct is evaluated during any execution or
flow through
• Is there an else or default or otherwise clause.
• Switch in C, C++ and Java: Use of break is important
Imperative Languages
51
Control Statements
• Example in C prints both “case zero” and “case one”
− int i = 0;
− switch (i) {
• case 0: printf("case zero");
• case 1: printf("case one");
− }
• In C#, absence of break or goto in the case statement will generate a
compilation error.
• Iteration Statements
− Function calling itself is called as recursion
− Recursion must include a terminal condition, otherwise the
program will not stop
Imperative Languages
52
Control Statements
• Fibonacci in C language
•
•
•
•
•
•
•
•
•
•
•
•
•
•
#include <stdio.h>
int fibonacci(int number)
{
if (number == 0) return 0;
if (number == 1) return 1;
return fibonacci(number-1) + fibonacci(number-2);
}
int main(void)
{
int i;
for (i=0; i <= 10; i++)
printf("%d ",fibonacci(i));
return 0;
}
Imperative Languages
53
Control Statements
• Counter controlled loops
− Type and scope of the loop variable.
− Value of loop variable at loop termination.
− Changing the loop variable within the loop body and its impact on
the loop control.
− Evaluation of loop parameters is done only during the first iteration
or during all iterations.
− Status of loop execution if the lower bound is greater than the
upper bound.
• FORTRAN 90:
− DO label var = start, finish [, stepsize]
− Loop variable must be an integer
− Loop variable cannot be changed within the loop but start and
finish can be changed.
− Change of loop parameters will not impact as they are evaluated
only once
Imperative Languages
54
Control Statements
• Pascal
−
−
−
−
for variable := initial (to | downto) final do statement
Loop variable must be an ordinal type of unusual scope
After termination, loop variable is considered undefined
Loop variables cannot be changed in the loop but loop parameters
can be changed.
− Changing loop parameters will have no impact.
• C language
−
−
−
−
for ([expr_1] ; [expr_2] ; [expr_3]) statement
Absence of expr_2 will make the loop infinite
Anything can be changed in the loop
First exp is evaluated only once but others are evaluated during
each iteration
• C++ language: Same as C language. C# and Java has a condition that
the control expression must be Boolean
Imperative Languages
55
Control Statements
• // Variable type should be specified before the for loop in C
• for (int i = 0; i < 5; i++) // Allowed in C++ but not in C
• // Java wants second part (condition) to be Boolean type
• for(i = 0; i = 5; i++) // Valid in C but not in Java and C#
•
Logically-Controlled loops
−
−
−
−
−
−
−
Based on pre-test or post-test
Pascal has pre-test and post-test: while-do, repeat-until
C, C++ has pre-test and post-test : while-do, do-while
Java and C# are similar to C or C++ but with Boolean condition
Java has no GOTO; C# has goto
Ada has pre-test but no post-test
Perl has 2 pre-test loops but no post-test: while, until
Imperative Languages
56
Control Statements
• User-located loop control mechanism
− Based on user located statements, using labels.
− Example in Ada
•
•
•
•
•
•
•
•
•
LOOP1:
while … loop
…
LOOP2:
for ... loop ...
exit LOOP1 when ..
...
end loop LOOP2;...
end loop LOOP1;
• Break in C, C++ and Java
− Break is applied only to a single level
− Java has break statement with label also
− continue statement is used to skip the remainder of the current
iteration and proceed for next iteration
• FORTRAN 90 has EXIT (like break) and CYCLE (like continue).
Imperative Languages
57
Control Statements
• Iteration based on data structures
− Iteration is based on the number of elements present in the data
structure
• C language: for (p=hdr; p; p=next(p)) { ... }
• C# language:
− int[] group = new int[]{1,2,3};
− foreach (int item in group) System.Console.WriteLine(b);
• Perl language: foreach $name (@names) { print $name }
• Unconditional branching
−
−
−
−
Not available in all languages
Causes irregular execution sequence and so called spaghetti code
Java does not posses unconditional branching statement
Pascal and FORTRAN allows label with GOTO statement to be
unsigned int constants. C# has goto with label.
− Algol 60 and C has label as identifiers.
Imperative Languages
58
Control Statements
• Long Jump in C language
− C language has setjmp and longjmp functions that could provide complex
flow of control
− setjmp() saves the contents of the registers and longjmp() retrieves those
contents. Register contents include those of stack pointer, frame pointer
and program counter.
Imperative Languages
59
Control Statements
• Guarded commands
− Some indication to indicate the end of the structure
− Guarded commands in Selection statements: Usage of fi
• if … fi
− Guarded commands in loop statements: Usage of od
• do … od
• Verification of the program
− Presence of unconditional branching makes verification difficult
− Guarded statements can help the verification process and presence
of selection and logical pre-test loops can make the verification
feasible
Imperative Languages
60
Stack and Subprograms
• Structure of run-time memory
− Java uses heap only but C++ class objects can be allocated in static
storage, stack or heap.
− C# uses both heap and stack depending on what and how things are
stored
− Stack has top-of-stack pointer that indicates the first available
empty position of the stack
Imperative Languages
61
Stack and Subprograms
62
• Local non-static variables are stored in the stack as part of the
activation record instance or stack frame
• Activation record is related to a subprogram call in the sense that it
indicates the return address, parameters and automatic local variables
• Closure is a pair consisting of the pointer to the subprogram code and
a pointer to the activation record
• In a subprogram, the formal parameter is the dummy variable used
within the subprogram and present in the header of the subprogram.
Actual parameters are those used in the subprogram call statement
and represent the value or address
• Subprogram has a single entry point. The caller is suspended during the
subprogram execution. When a subprogram execution terminates
control returns back to the caller.
Imperative Languages
Stack and Subprograms
• Semantics of a subprogram call is:
−
−
−
−
Execution status of the caller is saved.
Parameter passing process is carried out.
Pass the return address to the callee.
Transfer control to the callee.
• Subprogram definition: Description of the action of the subprogram
abstraction.
• Subprogram call: Explicit request to the subprogram that should be executed.
• Subprogram header: First line of the subprogram definition that includes the
name of the subprogram and their formal parameters.
• Parameter profile: Type, number and order of the parameters.
• Protocol: Protocol of a subprogram indicates the parameter profile plus the
return type.
• Subprogram declaration: Provides the protocol but not the body of the
subprogram.
Imperative Languages
63
Stack and Subprograms
• Matching actual and formal parameters can be positional or keyword
based
− Positional is matched based on the order of parameters
− Keyword is based on formal parameter names
• SORT(LIST => X, LENGTH => N);
• Stack-dynamic:
− Can help recursion by storing the values when the subprogram is to
be executed and storage is freed when subprogram exists
• Keeping local variables static makes sure the data is not lost from the
stack
• FORTRAN 77 and 90 supports static storage.
• C language uses stack-dynamic by default when static reserved word is
used, storage is made as static
• Pascal, Java and Ada support dynamic storage only
Imperative Languages
64
Stack and Subprograms
• In C#, reference types like class, interface, delegate,
object and string which are inherited from System.Object
are stored on the heap. One exception to this is the
generic object of System.Object.
• In C#, value types like bool, byte, char, int, long, float,
etc which come from System.ValueType are allocated
based on where they are declared. A value type part of an
object will be allocated in the heap
Imperative Languages
65
Parameter Passing Methods
• Parameter passing
− Input or output or both
− Passed as a copy or as an access path with pointer (reference)
• Pass by value (in mode)
− Called as pass by copy
− Data is passed as copy (extra space is required) or via reference
(write protection is needed if the data not be changed by
subprogram)
− Pass by constant value: Value is passed as a constant and so cannot
be changed
• Pass by result (out mode)
− Return the local value of called program to caller
− Physical move is mostly used
− Return value depends on which formal parameter is matched to the
actual parameter
Imperative Languages
66
Parameter Passing Methods
• Pass by value result (inout mode)
− Double copying is done for both input and output
− Drawbacks include those of pass by result and pass by
value
• Pass by reference (inout mode)
−
−
−
−
Called as pass by sharing
Uses access path to share values
Might be slower due to the use of access path
Actual parameter collisions
• Mapping different values to same parameter
• For Example, void fun (int &a, int &b) { }
• Calling the function: fun(x, x);
Imperative Languages
67
Parameter Passing Methods
• Pass by reference (inout mode)
− Array element collisions
• // if i is not equal to j, then they refer to different elements.
• // They are considered differently in the function and so ok.
• fun(a[i], a[j]);
• // if i and j are same, then they refer to the same element.
• // At the function, they are considered different and so a
mismatch.
• Also, fun(a, a[i]);
− Type checking in C language:
− int i = 5; float j = 5.0;
− void proc(int a[]) { printf("%d\n",a[0]); }
− int main() { proc(&i);
/* pointer to an integer */
− // pointer to floating point -- warning incompatible pointer type
− proc(&j); return 0; }
− Passing floating point to integer array gives compilation warning
Imperative Languages
68
Parameter Passing Methods
• Pass by name (inout mode)
− Parameters are passed by textual substitution of the actual
parameter for the corresponding formal parameter
− Actual binding of the value or address takes place at the time of
variable reference or assignment. This late binding provides
flexibility
− Not used widely
• C Language uses pass by value and pass by reference with pointers.
• C++ language uses pass by value, pass by reference with pointers and
pass by reference with references.
• Java handles parameters like C++ but without references.
• Perl supports only pass by reference with references
Imperative Languages
69
Parameter Passing Methods
• Modern languages implement parameter passing mechanisms using the
run-time stack, which is initialized and maintained by run-time system
Imperative Languages
70
Parameter Passing Methods
•
In languages like C and C++, programmer is required to include the
size of all the subscripts of the array except the first subscript, in the
actual parameter
−
•
Semantics of the subprogram is as below:
−
−
−
−
•
void fun (int matrix [][10]);
While using pass by value result parameter passing, move the
current values of those parameters to their corresponding actual
parameters.
While passing a function, move the functional value to a place
from which the caller can get it.
Restore the execution status of the caller.
Transfer control back to the caller.
Design of Parameter Passing
−
−
One way or two way; Whether parameters are type checked?
What is the correct referencing environment for a subprogram
that was sent as a parameter?
Imperative Languages
71
Parameter Passing Methods
72
•
Earlier version of Pascal and FORTRAN 77 do not type check the
parameters but later versions of Pascal and FORTRAN 90 do.
•
Ada does not allow subprogram parameters.
•
Java also does not allow method names to be passed as parameters.
•
C and C++ allow programmers to pass pointers to functions and does
type check on the parameters.
•
Visibility in referencing environment is referred to as shallow binding
or deep binding or ad hoc binding
•
Referencing environment of a subprogram (sub2) using shallow
binding includes the subprogram (sub4) that has called this
subprogram (sub2), which was sent as parameter.
•
Deep binding includes only the declaration scope and thus referencing
environment of the subprogram (sub2) includes subprogram (sub1),
where the subprogram (sub2) is declared.
Imperative Languages
Parameter Passing Methods
•
•
•
•
•
•
73
Start Sub1
− Start Sub2 … End Sub2
− Start Sub3
Call Sub4(Sub2)
End Sub3
− Start Sub4(Subx)
Call Subx
End Sub4
− Call Sub3
End Sub1
Ad hoc binding includes the subprogram that passed the subprogram
(sub2) as a parameter. Ad hoc binding was never used.
For static-scoped languages, using deep binding is more natural.
Similarly, for dynamic-scoped languages, using shallow binding is
more natural
Shallow binding: Here, Sub2 is invoked by Sub4 and Sub4 is invoked
from Sub3 and Sub3 is invoked from Sub1.
− Sub2, Sub4, Sub3, Sub1
Deep binding: Here, Sub2 is declared in Sub1.
− Sub2, Sub1
Imperative Languages
Parameter Passing Methods
•
•
74
Overloaded subprograms
− Overloaded subprogram is one that has the same name as another
subprogram in the same referencing environment
− C++, Java, C# and Ada have inbuilt overloaded programs
− Generic or polymorphic Subprograms are those subprograms
that take different types of parameters at different activations
− ad hoc polymorphism: two or more subprograms exist with the
same name but with different parameters.
− Subtype polymorphism uses the subtype related between types
to have many possible types
Separate and independent compilation
− Independent compilation is the process of compilation of some of
the units of a program separately from others and thus not
including the benefit of interfaces. Ex. FORTRAN II to FORTRAN 77
− Separate compilation is the process of compilation of some of the
units of a program separately from others but with using interface
information to check the correctness of the interface between
the two parts. Ex. Fortran 90, Ada, C++, C# and Java
− Pascal supports neither of them
Imperative Languages
Parameter Passing Methods
•
Returning of values from functions
−
−
−
−
•
Ada allows any type to be returned but does not consider
subprograms as a type
Fortran and Pascal allow only simple types to be returned from a
function.
C allows any type except functions and arrays as a return type
from the function.
C++, C# and Java work similar to C language but also allow
objects to be returned
Accessing Non-Local environments
−
−
FORTRAN COMMON blocks
• Common block can contain any number of variables of any
type. If a subprogram needs any variable from them, the
whole block should be declared
• common / name / list-of-variables
Static scoping: Using static global variables
Imperative Languages
75
Parameter Passing Methods
•
Accessing Non-Local environments
−
External declarations as in C language
• #include "header.h" // user defined header file
• extern void proc(int i);
• int main() { proc(100); return 0;}
• // header.h file
• void proc(int f) { printf("Value = %d\n",f); }
Imperative Languages
76
Parameter Passing Methods
•
External Modules
−
−
Modules are provided using public interface
Can be accessed using: import in Java, using in C++ or C#
•
Dynamic Scope: References to non-static variables could be handled
using dynamic scope
•
User-defined overloaded operators
−
•
Ada and C++ permits user-defined overloaded operators but Java
does not.
Coroutines (Called as Symmetric Control)
−
−
−
−
Subprogram with multiple entry points
Coroutine call is named as resume
Coroutines can be used in concurrent processing
To perform coroutine, goto is needed in modern languages
Imperative Languages
77
Parameter Passing Methods
•
#include <stdio.h>
•
int coroutine1(void) { static int i, state = 0, sum = 0;
•
switch (state) {
−
−
•
78
Output:
Result = 10
CASE 1 Result = 10
case 0: for (i = 0; i < 5; i++) { sum = sum + i; }
• state = 1; // states becomes 1
• return sum;
case 1: printf("CASE 1"); return sum; } }
int main() { int result; result = coroutine1(); printf("Result = %d\n",
result); result = coroutine1(); printf("Result = %d\n", result); return 0; }
Resume
from Main
Program
Coroutine A1
.
.
Resume A2
Coroutine A2
.
.
Resume
from Main
Program
Resume A1
.
.
.
.
Resume A2
Resume A1
.
.
.
.
Imperative Languages
Coroutine A2
Coroutine A1
.
.
Resume A2
.
.
.
.
.
First
Resume
Subsequent
Resume
.
.
Resume A1
.
.
.
.
Parameter Passing Methods
•
Implementing Subprograms
−
•
While implementing subprograms, we need to store the status
information of the caller, parameters or arguments, return
address, functional value (if it is a function), static and dynamic
links. This storage is called activation record
Testing on our programs
−
−
−
−
Pascal: free Pascal compiler (open source compiler available from
http://www.freepascal.org) on Windows platform.
• Compile: fpc.exe filename.pas
Run: filename
C and C++: gcc and g++ compiler. On Windows platform, gcc and
g++ compilers can be used with cygwin.
• Compile C programs: gcc filename.c Run: a.out or a.exe
C#: Sharp Develop version 2.2.1.
Java: use SDK. We have used JEE 5 SDK because we were
developing many other Java related programs in Java.
Imperative Languages
79