PPL Unit02
PPL Unit02
Languages
SE Sem II
Unit II
Structuring the Data, Computations and Program
Unit II
Structuring the Data, Computations and Program
• Elementary Data Types : Primitive data Types, Character String types, User Defined Ordinal Types,
Array types, Associative Arrays, Record Types, Union Types, Pointer and reference Type.
• Subprograms : Fundamentals of Sub Programs, Design Issues for Subprograms, Local referencing
Environments, Parameter passing methods.
• Abstract Data Types and Encapsulation Construct : Design issues for Abstraction, Parameterized
Abstract Data types, Encapsulation Constructs, Naming Encapsulations.
Primitive data Types
• Data types that are not defined in terms of other types are called primitive data types.
• Nearly all programming languages provide a set of primitive data types. Some of the primitive types are
merely reflections of the hardware—for example, most integer types.
• There are 8 primitive data types in Java: byte, char, short, int, long, float, double and Boolean
• In python there are 4 primitive data types integer ,floating , Boolean, string.
Primitive data structure is a kind of data structure that stores the data of only one
type.
Non-primitive data structure is a type of data structure that can store the data
of more than one type
Primitive data Types
Primitive data Types
Numeric Types (Integer, Floating Point)
Integer
Java includes four signed integer sizes: byte, short, int, and long.
Some languages, for example, C++ and C#, include unsigned integer types, which are simply types for
integer values without signs. Unsigned types are often used for binary data.
A signed integer value is represented in a computer by a string of bits, with one of the bits (typically the
leftmost) representing the sign.
A negative integer could be stored in sign-magnitude notation, in which the sign bit is set to indicate negative
and the remainder of the bit string represents the absolute value of the number.
Primitive data Types
Integer
The value of the whole numbers can be determined by the sign used before it. If the number has ‘+’ sign or
no sign it will be considered as positive. If the number has ‘–’ sign it will be considered as negative.
Example:
+43 or 43 is a positive number
8 bits.
Floating-point values are represented as fractions and exponents, a form that is borrowed from scientific
notation.
Most languages include two floating-point types, often called float and double.
The float type is the standard size, usually being stored in four bytes of memory.
The double type is provided for situations where larger fractional parts and/or a larger range of exponents is
needed.
The collection of values that can be represented by a floating-point type is defined in terms of precision and
range.
Precision is the accuracy of the fractional part of a value, measured as the number of bits.
Range is a combination of the range of fractions and, more important, the range of exponents.
Primitive data Types
Floating Point
Older computers used a variety of different representations for floating-point values. However, most newer
machines use the IEEE Floating-Point Standard 754 format.
IEEE floating point representation for binary real numbers consists of three parts (Single/Double precision).
1.Sign
2. Mantissa/Fraction/significand
3. Exponent
Primitive data Types
Floating Point
Primitive data Types
Complex Number
Some programming languages support a complex data type—for example, Fortran and Python.
In Python, the imaginary part of a complex literal is specified by following it with a j or J—for example,
(7 + 3j)
Primitive data Types
Decimal
Decimal data types store a fixed number of decimal digits, with the decimal point at a fixed position in
the value.
The decimal module provides support for fast correctly-rounded decimal floating point arithmetic.
Advantage: accuracy
This is not a built-in type, but it behaves like one in its most basic usage. String values must be surrounded by
double quotes.
Library functions that produce strings often supply the null character.
Assignment
Comparison (=, >, etc.)
Catenation
Substring reference
Pattern matching
Some of the most commonly used library functions for character strings in C and C++ are
• strlen : returns the number of characters, not counting the null – In Java, strings are supported as a primitive
type by String class
Character String Types
strcpy() is a standard library function in C/C++ and is used to copy one string to another. In C it is present
in string.h header file and in C++ it is present in cstring header file.
strcpy(dest, src); dest: Pointer to the destination array where the content is to be copied.
src: string which will be copied.
#include<stdio.h>
#include<string.h>
int main ()
{
char str1[]="Hello";
char str2[] = " SINHGAD"; Output:
char str3[40];
char str4[40];
char str5[] = “How are you?"; str1: Hello
str2: SINHGAD
strcpy(str2, str1); str3: Copy successful
strcpy(str3, "Copy successful"); str4: How are you?
strcpy(str4, str5);
printf ("str1: %s\nstr2: %s\nstr3: %s\nstr4:
%s\n", str1, str2, str3, str4);
return 0;
}
Character String Types
Python includes strings as a primitive type In F#, strings are a class. Individual
and has operations for substring reference, characters, which are represented in
catenation, indexing to access individual Unicode UTF-16, can be accessed, but
characters, as well as methods for searching not changed. Strings can be catenated
and replacement with the + operator
Character String Types
Pascal - Not primitive, assignment and Perl - Patterns are defined in terms of
comparison only (of packed arrays) regular expressions A very powerful facility!
• Strings are supported by the String class, whose values are constant strings (String class is immutable).
• StringBuffer class, whose values are changeable and are more like arrays of single characters(StringBuffer class
is mutable).
1. Static length string : the length can be static and set when the string is created. Such a string is called a
static length string. the immutable objects of Java’s String class, as well as similar classes in the C++ standard
class library.
2. Limited dynamic length strings : This option is to allow strings to have varying length up to a declared
and fixed maximum set by the variable’s definition
3. Dynamic length strings : This option is to allow strings to have varying length with no maximum, as in
JavaScript, Perl, and the standard C++ library.
Character String Types
Evaluation
The addition of strings as a primitive type to a language is not costly in terms of either language or
compiler complexity.
Therefore, it is difficult to justify the omission of primitive string types in some contemporary
languages.
String operations such as simple pattern matching and catenation are essential and should be included
for string type values.
Character String Types
Implementation of Character String
Types
The addition of strings as a primitive type to a language is not costly in terms of either language or
compiler complexity.
Therefore, it is difficult to justify the omission of primitive string types in some contemporary
languages.
String operations such as simple pattern matching and catenation are essential and should be included
for string type values.
User-Defined Ordinal Types
• An ordinal type is one in which the range of possible values can be easily associated with the set of
positive integers.(The range of values is mapped onto the set of positive integers )
• In Java, for example, the primitive ordinal types are integer, char, and boolean.
• There are two user-defined ordinal types that have been supported by programming languages:
enumeration and subrange.
Enumeration
user-defined
ordinal types
Subrange
User-Defined Ordinal Types
Enumeration
• An enumeration type is one in which all of the possible values, which are named constants, are provided, or
enumerated, in the definition.
• It provide a way of defining and grouping collections of named constants, which are called enumeration
constants.
• The enumeration constants are typically implicitly assigned the integer values, 0, 1, . . . . .
• Enumerations are created using the class In ML, enumeration types are defined as new types
syntax, which makes them easy to read and with datatype declarations.
write
• Member values can be anything: int, str, etc.
C - Enum
Readability is enhanced very directly: Named values are easily recognized, whereas coded values are
not.
the enumeration types of Ada, C#, F#, and Java 5.0 provide two advantages
(1) No arithmetic operations are legal on enumeration types; this prevents adding days of the
week
(2)No enumeration variable can be assigned a value outside its defined range
C treats enumeration variables like integer variables, it does not provide either of these two advantages
C++ is a little better. Numeric values can be assigned to enumeration type variables only if they are cast
to the type of the assigned variable.
A subrange type is a contiguous subsequence of an ordinal type. For example, 12..14 is a subrange of
integer type. Subrange types were introduced by Pascal and are included in Ada. There are no design issues
that are specific to subrange types.
Subrange types enhance readability by making it clear to readers that variables of subtypes can store only
certain ranges of values.
Reliability is increased with subrange types, because assigning a value to a subrange variable that is outside
the specified range is detected as an error, either by the compiler (in the case of the assigned value being a
literal value) or by the run-time system (in the case of a variable or expression).
Array Types
If any of the subscript expressions in a reference include variables, then the reference will require an
additional run-time calculation to determine the address of the memory location being referenced.
In many languages, such as C, C++, Java, Ada, and C#, all of the elements of an array are required to be
of the same type.
In these languages, pointers and references are restricted to point to or reference a single type. So the
objects or data values being pointed to or referenced are also of a single type.
Array Types
Design Issues
The primary design issues specific to arrays are the following:
There are five categories of arrays, based on the binding to subscript ranges, the binding to storage, and from
where the storage is allocated.
The category names indicate the design choices of these three. In the first four of these categories, once the
subscript ranges are bound and the storage is allocated, they remain fixed for the lifetime of the variable.
A static array is one in which the subscript ranges are statically bound and storage allocation is static (done
before run time).
The disadvantage is that the storage for the array is fixed for the entire execution time of the program.
Array Types
Array Categories
A fixed stack-dynamic array is one in which the subscript ranges are statically bound, but the allocation is
done at declaration elaboration time during execution.
• The advantage of fixed stack-dynamic arrays over static arrays is space efficiency. A large array in one
subprogram can use the same space as a large array in a different subprogram
• The disadvantage is the required allocation and deallocation time.
A stack-dynamic array is one in which both the subscript ranges and the storage allocation are dynamically
bound at elaboration time.
• Once the subscript ranges are bound and the storage is allocated, however, they remain fixed during the
lifetime of the variable.
• The advantage of stack-dynamic arrays over static and fixed stack-dynamic arrays is flexibility. The size of
an array need not be known until the array is about to be used.
Array Types
Array Categories
A fixed heap-dynamic array is similar to a fixed stack-dynamic array, in that the subscript ranges and the
storage binding are both fixed after storage is allocated.
• The differences are that both the subscript ranges and storage bindings are done when the user program requests
them during execution, and the storage is allocated from the heap, rather than the stack.
• The advantage of fixed heap-dynamic arrays is flexibility—the array’s size always fits the problem.
• The disadvantage is allocation time from the heap, which is longer than allocation time from the stack.
A heap-dynamic array is one in which the binding of subscript ranges and storage allocation is dynamic and can
change any number of times during the array’s lifetime.
• The advantage of heap-dynamic arrays over the others is flexibility: Arrays can grow and shrink during program
execution as the need for space changes.
• The disadvantage is that allocation and deallocation take longer and may happen many times during execution of
the program
Array Types
Initialization of Array
Arrays of strings in C and C++ can also be initialized with string literals. In this case, the array is one of pointers to
characters.
For example,
char *names [] = {"Bob", "Jake", "Darcie"};
character strings in C and C++ are implemented as arrays of char. These arrays can be initialized to string constants, as
in
char name [] = "freddie";
In Java, similar syntax is used to define and initialize an array of references to String objects.
For example,
String[] names = ["Bob", "Jake", "Darcie"];
Ada provides two mechanisms for initializing arrays in the declaration statement: by listing them in the order in which
they are to be stored, or by directly assigning them to an index position using the => operator, which in Ada is called an
arrow. For example, consider the following:
List : array (1..5) of Integer := (1, 3, 5, 7, 9);
Bunch : array (1..5) of Integer := (1 => 17, 3 => 34,
others => 0);
Array Types
Array Operations
An array operation is one that operates on an array as a unit. The most common array operations are
assignment, catenation, comparison for equality and inequality, and slices.
The C-based languages do not provide any array operations, except through the methods of Java, C++, and
C#.
Ada allows array assignments, including those where the right side is an aggregate value rather than an array
name. Ada also provides catenation, specified by the ampersand (&).
Python’s arrays are called lists, although they have all the characteristics of dynamic arrays.
Python also has operations for array catenation (+) and element membership (in).
Like Python, the elements of Ruby’s arrays are references to objects. when a == operator is used between two
arrays, the result is true only if the two arrays have the same length and the corresponding elements are equal.
Ruby’s arrays can be catenated with an Array method.
Array Types
Array Operations
F# includes many array operators in its Array module. Among these are
Arrays and their operations are the heart of APL; it is the most powerful array-processing language ever
devised
In APL, the four basic arithmetic operations are defined for vectors (single-dimensioned arrays) and matrices,
as well as scalar operands.
For example,
It is important to realize that a slice is not a new data type. Rather, it is a mechanism for referencing
part of an array as a unit.
A single integer expression parameter is interpreted as a subscript, in which case slice returns the
element with the given subscript.
If slice is given two integer expression parameters, the first is interpreted as a beginning subscript and
the second is interpreted as the number of elements in the slice.
Associative Array Types
To define an associative array we use the usual parenthesis notation, but the array itself is prefixed by a %
sign. Suppose we want to create an array of people and their ages.
Consider a simple example. Get the dictionary Capitals, where index is the name of the country, and the
value — the name of the capital of this country. Now for a row with the name of the country we can easily
idenify its capital.
Associative Array Types
Associative array will have their index as string so that you can establish a strong association
between key and values. The associative arrays have names keys that is assigned to them.
A record is an aggregate of data elements in which the individual elements are identified by
names and accessed through offsets from the beginning of the structure.
The fundamental difference between a record and an array is that record elements, or fields, are not
referenced by indices.
Instead, the fields are named with identifiers, and references to the fields are made using these
identifiers.
In C, C++, and C#, records are supported with the struct data type.
The EMPLOYEE-RECORD record consists of the EMPLOYEE-NAME record and the HOURLY-RATE
field.
The numerals 01, 02, and 05 that begin the lines of the record declaration are level numbers, which indicate
by their relative values the hierarchical structure of the record.
Record Types
Ada uses a different syntax for records; rather than using the level numbers of COBOL, record structures
are indicated in an orthogonal way by simply nesting record declarations inside record declarations.
In Ada, records cannot be anonymous—they must be named types. Consider the following Ada declaration
Record Types
In Java and C#, records can be defined as data classes, with nested records defined as
nested classes.
employee.name = "Freddie"
employee.hourlyRate = 13.20
These assignment statements create a table (record) named employee with two elements
(fields) named name and hourlyRate, both initialized.
Union Types
A union is a type whose variables may store different type values at different times during program
execution
Like Structures, union is a user defined data type. In union, all members share the same memory location.
Structures allocate enough space to store all their members, whereas unions can only hold one member
value at a time.
Design Issues
The other fundamental question is how to syntactically represent a union.
In some designs, unions are confined to be parts of record structures, but in others they are
not.
So, the primary design issues that are particular to union types are the following:
• Should type checking be required? Note that any such type checking must be dynamic.
The unions in these languages are called free unions, because programmers are allowed complete freedom from type
checking in their use.
• Type checking of unions requires that each union construct include a type
indicator.
It allows the user to specify variables of a variant record type that will store only one of the possible type
values in the variant
Union Types
Unions in F#
A union is declared in F# with a type statement using OR operators (|) to define the components.
For example, we could have the following:
In this example, intReal is the union type. IntValue and RealValue are constructors. Values of type intReal
can be created using the constructors as if they were a function, as in the following examples
Union Types
Unions in F#
To display the type of the intReal union, the following function could be used:
Pointer and Reference Types
In C++, it is explicitly specified with the asterisk (*) as a prefix unary operator. Consider the
following example of dereferencing:
If ptr is a pointer variable with the value 7080 and the cell whose address is 7080 has the value 206,
then the assignment
j = *ptr
sets j to 206. This process is shown in Figure
Pointer and Reference Types
Using Pointers in C++
The asterisk you used to declare a pointer is the same asterisk that you use for multiplication.
However, in this statement the asterisk is being used to designate a variable as a pointer.
Following are the valid pointer declaration −
The actual data type of the value of all pointers, whether integer, float, character, or otherwise, is the
same, a long hexadecimal number that represents a memory address.
The only difference between pointers of different data types is the data type of the variable or constant
that the pointer points to
Pointer and Reference Types
Using Pointers in C++
There are few important operations, which we will do with the pointers very frequently.
(a) We define a pointer variable.
(b) Assign the address of a variable to a pointer.
(c) Finally access the value at the address available in the pointer variable.
This is done by using unary operator * that returns the value of the variable located at the address
specified by its operand
C and C++ include pointers of type void *, which can point at values of
any type. They are in effect generic pointers. However, type checking is not a
problem with void * pointers, because these languages disallow dereferencing
them. One common use of void * pointers is as the types of parameters of
functions that operate on memory.
Pointer and Reference Types
Using Pointers in C++
When the code is compiled and executed, it produces
result something as follows −
Pointer and Reference Types
Using Pointers in Ada
pool access types – general access types – anonymous access types – access to subprogram types.
Pointer and Reference Types
Dangling Pointers
References vs Pointers
References are often confused with pointers but three major differences between references and pointers are
1. You cannot have NULL references. You must always be able to assume that a reference is connected to a
legitimate piece of storage.
2. Once a reference is initialized to an object, it cannot be changed to refer to another object. Pointers can be
pointed to another object at any time.
3. A reference must be initialized when it is created. Pointers can be initialized at any time.
Pointer and Reference Types
Reference Types
Creating References in C++
you can access the contents of the variable
through either the original variable name or the
reference. For example, suppose we have the
following example −
int i = 17;
We can declare reference variables for i as follows.
int& r = i;
Expressions and Assignment
Statements Reference Types
Expressions are used to compute the mathematical calculations or it is used to apply some condition in
programming languages
Assignment statements are used to assign the value of expression or use to assign some fix value to
variables.
Arithmetic Expressions
Most of the characteristics of arithmetic expressions in programming languages were inherited from
conventions that had evolved in mathematics.
In programming languages, arithmetic expressions consist of operators, operands, parentheses, and
function calls.
An operator can be unary, meaning it has a single operand, binary, meaning it has two operands, or
ternary, meaning it has three operands.
[ Unary :- (i++), Binary: (a + b), Ternary: (a > b ? a : b) ]
In most programming languages, binary operators are infix, which means they appear between their
operands. some operators that are prefix, which means they precede their operands.
[infix example, A + B * C ] [prefix example, + A * B C]
The purpose of an arithmetic expression is to specify an arithmetic computation.
An implementation of such a computation must cause two actions: fetching the operands, usually from
memory, and executing arithmetic operations on those operands
Arithmetic Expressions
Precedence
The value of an expression depends at least in part on the order of evaluation of the operators in the
expression.
The operator precedence rules for expression evaluation partially define the order in which the operators of
different precedence levels are evaluated.
The operator precedence rules for expressions are based on the hierarchy of operator priorities, as seen by the
language designer. The operator precedence
rules of the common imperative languages are nearly all the same, because they are based on those of
mathematics.
In these languages, exponentiation has the highest precedence, followed by multiplication and division on
the same level, followed by binary addition and subtraction on the same level.
Arithmetic Expressions
Precedence
Precedence order. When two operators share an operand the operator with the higher precedence goes first.
For example, 1 + 2 * 3 is treated as 1 + (2 * 3),
whereas 1 * 2 + 3 is treated as (1 * 2) + 3
since multiplication has a higher precedence than addition.
Associativity. When an expression has two operators with the same precedence, the expression is evaluated
according to its associativity.
For example x = y = z = 17 is treated as x = (y = (z = 17)),
leaving all three variables with the value 17,
since the = operator has right-to-left associativity
On the other hand, 72 / 2 / 3 is treated as (72 / 2) / 3
since the / operator has left-to-right associativity.
Arithmetic Expressions
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.
For example, (A + B) * C
although multiplication has precedence over addition, in the expression the addition will be evaluated
first. Mathematically, this is perfectly natural
Languages that allow parentheses in arithmetic expressions could dispense with all precedence rules and
simply associate all operators left to right or right to left.
The disadvantage of this scheme is that it makes writing expressions more tedious, and it also seriously
compromises the readability of the code.
Arithmetic Expressions
Conditional Expressions
What is a Conditional Statement in Programming language ?
Conditional Statements in programming are used to make decisions based on the conditions.
Conditional statements execute sequentially when there is no condition around the statements.
If you put some condition for a block of statements, the execution flow may change based on the result
evaluated by the condition.
This process is called decision making in programming.
Arithmetic Expressions
Arithmetic operators are often used for more than one purpose. For example, + usually is used to specify
integer addition and floating-point addition. Some languages—Java, for example—also use it for string
catenation. This multiple use of an operator is called operator overloading and is generally thought to be
acceptable, as long as neither readability nor reliability suffers.
As an example of the possible dangers of overloading, consider the use of the ampersand (&) in C++. As a
binary operator, it specifies a bitwise logical AND operation.
As a unary operator with a variable as its operand, the expression value is the address of that variable. In
this case, the ampersand is called the address-of operator.
For example, the execution of
x = &y;
causes the address of y to be placed in x.
What is Operator Overloading in C++?
Have you ever wondered about this type of code –
why is z== 15 and s3== Abhigautam? This is because
operators have different meanings for different types
of operands.
For an integer type, the + operator gives the sum of
two numbers, and for the string type it concatenates
(joins) them.
So, operator overloading is all about giving new
meaning to an operator.
But: 1) You cannot set new meaning to an operator
for a built-in type.
C++ has a few operators that cannot be overloaded.
Among these are the class or structure member 2)You cannot create new operators.
operator (.) and the scope resolution operator (::).
Overloaded Operators
Interestingly, operator overloading was one of the C++ features that was not copied into
Java.
Java doesn't supports operator overloading because it's just a choice made by its
creators who wanted to keep the language more simple.
Every operator has a good meaning with its arithmetic operation it performs.
Operator overloading allows you to do something extra than what for it is expected for.
Java only allows arithmetic operations on elementary numeric types.
If you allow a developer to do operator overloading they will come up with multiple
meanings for the same operator which will make the learning curve of any developer
hard and things more confusing and messy.
Type Conversions
The process of converting the value of one data type (integer, string, float, etc.) to another data type is called
type conversion. Python has two types of type conversion.
• Implicit Type Conversion
• Explicit Type Conversion
Implicit Type Conversion
Automatic conversion of a value from one data type to another by a programming language, without the
programmer specifically doing so, is called implicit type conversion.
It happens whenever a binary operator has two operands of different data types. Depending on the operator, one
of the operands is going to be converted to the data type of the other. It could be promoted or demoted depending
on the operator.
55 + 1.75
In this example, the integer value 55 is converted to a floating-point value of 55.0. It was promoted.
Type Conversions
Explicit Type Conversion
Most languages have a method for the programmer to change or cast a value from one data type to another;
called explicit type conversion. Some languages support a cast operator.
The cast operator is a unary operator; it only has one operand and the operand is to the right of the operator.
The operator is a set of parentheses surrounding the new data type. Other languages have functions that
perform explicit type conversion
A widening conversion converts a value to a type that can include at least approximations of all of the values
of the original type. For example, converting an int to a float in Java is a widening conversion.
Widening conversions are nearly always safe, meaning that the magnitude of the converted value is
maintained.
Narrowing conversions are not always safe— sometimes the magnitude of the converted value is changed in
the process
Type Conversions
Relational Expressions
A relational operator is an operator that compares the values of its two operands.
A relational expression has two operands and one relational operator.
The value of a relational expression is Boolean, except when Boolean is not a type
included in the language.
The relational operators are often overloaded for a variety of types.
The operation that determines the truth or falsehood of a relational expression depends
on the operand types.
It can be simple, as for integer operands, or complex, as for character string operands.
Typically, the types of the operands that can be used for relational operators are numeric
types, strings, and ordinal
types.
Relational Expressions
Boolean Expressions
The println statement will be executed if wet and cold are both true, or if poor and hungry are both true.
Short-Circuit Evaluation
Assignment operators are used to assigning value to a variable. The left side operand of the assignment
operator is a variable and right side operand of the assignment operator is a value.
The value on the right side must be of the same data-type of the variable on the left side otherwise the
compiler will raise an error.
“ = ” This is the simplest assignment operator.
This operator is used to assign the value on the right to the variable on the left.
ALGOL 60 pioneered the use of := as the assignment operator, which avoids the confusion of
assignment with equality
Assignment Statements
a=a+b
The operators ++ for increment, and –– for decrement, can be used either in expressions or to
form stand-alone single-operator assignment statements.
Assignment Statements
Compound Assignment Operators
In this statement, the next character from the standard input file, usually the keyboard, is gotten with getchar
and assigned to the variable ch.
The result, or value assigned, is then compared with the constant EOF.
If ch is not equal to EOF, the compound statement {...} is executed.
Note that the assignment must be parenthesized—in the languages that support assignment as an expression,
the precedence of the assignment operator is lower than that of the relational operators.
Without the parentheses, the new character would be compared with EOF first. Then, the result of that
comparison, either 0 or 1, would be assigned to ch.
Assignment Statements
Multiple Assignments
Several recent programming languages, including Perl, Ruby, and Lua, provide multiple-target, multiple-
source assignment statements.
For example, in Perl one can write
The semantics is that 20 is assigned to $first, 40 is assigned to $second, and 60 is assigned to $third.
If the values of two variables must be interchanged, this can be done with a single assignment, as
with
Assignment Statements
Assignment in Functional Programming Languages
All of the identifiers used in pure functional languages and some of them used in other functional languages
are just names of values.
As such, their values never change. For example, in ML, names are bound to values with the val declaration,
whose form is exemplified in the following:
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.
Mixed-Mode Assignment
A control structure is a control statement and the statements whose execution it controls.
1. Selection Statements
2. Iterative Statements
3. Unconditional Branching
A selection statement provides the means of choosing between two or more execution paths in a program.
Such statements are fundamental and essential parts of all programming languages.
A selection statement selects among a set of statements depending on the value of a controlling expression.
The selection statements are the if statement and the switch statement, which are discussed in the following
sections.
Selection statements fall into two general categories: two-way and n-way, or multiple selection.
Two-Way Selection Statements
Although the two-way selection statements of contemporary imperative languages are quite similar, there are
some variations in their designs.
The general form of a two-way selector is as follows
Design Issues
Two-Way Selection Statements
In those cases where the then reserved word (or alternative marker) is used, there is less
need for the parentheses, so they are often omitted, as in Ruby.
In C89, which did not have a Boolean data type, arithmetic expressions were used as
control expressions.
This can also be done in Python, C99, and C++.
Two-Way Selection Statements
Clause Form
In many contemporary languages, the then and else clauses appear as either single statements or
compound statements.
Many languages use braces to form compound statements, which serve as the bodies of then and else
clauses.
In Fortran 95, Ada, Python, and Ruby, the then and else clauses are statement sequences, rather than
compound statements.
Python uses indentation to specify compound statements. For example,
rather than then, a colon is used to introduce the then clause in Python.
Two-Way Selection Statements
Nesting Selectors
problem of syntactic ambiguity of a straightforward grammar for a two-way selector statement.
That ambiguous grammar was as follows:.
Nesting Selectors
The first interpretation of the selector example at the beginning of this
section, in which the else clause is matched to the nested if, can be written
in Ruby as follows:
Because the end reserved word closes the nested if, it is clear that the
nested if, the else clause would be matched with the inner if.
Two-Way Selection Statements
Selector Expressions
In the functional languages ML, F#, and LISP, the selector is not a statement; it is an expression that
results in a value.
Therefore, it can appear anywhere any other expression can appear.
Consider the following example selector written in F#:
This creates the name y and sets it to either x or 2 * x, depending on whether x is greater than zero.
Multiple-Selection Statements
The multiple-selection statement allows the selection of one of any number of statements or
statement groups.
It is, therefore, a generalization of a selector.
In fact, two-way selectors can be built with a multiple selector.
The need to choose from among more than two control paths in a program is common.
Although a multiple selector can be built from two-way selectors and gotos, the resulting
structures are cumbersome, unreliable, and difficult to write and read.
Therefore, the need for a special structure is clear and that is multiple-selection statement.
Multiple-Selection Statements
Examples of Multiple Selectors
The primary categories are defined by how designers answered two basic design questions:
• How is the iteration controlled?
• Where should the control mechanism appear in the loop statement?
Iterative Statements
The for Statement of the C-Based Languages
The general form of C’s for statement isrange, Integer.
The loop body can be a single statement, a compound statement, or a null statement.
The expressions in a for statement are often assignment statements.
The first expression is for initialization and is evaluated only once, when the for statement execution begins.
The second expression is the loop control and is evaluated before each execution of the loop body.
The last expression in the for is executed after each execution of the loop body. It is often used to increment the
loop counter.
Iterative Statements
The for Statement of Python
The general form of Python’s for is
In this function, the parameter loopBody is the function with the body of the loop and the parameter reps is
the number of repetitions.
The reserved word rec appears before the name of the function to indicate that it is recursive.
Iterative Statements
Logically Controlled Loops
In many cases, collections of statements must be repeatedly executed, but the repetition
control is based on a Boolean expression rather than a counter.
For these situations, a logically controlled loop is convenient. Actually, logically controlled
loops are more general than counter-controlled loops.
Every counting loop can be built with a logical loop, but the reverse is not true.
Also, recall that only selection and logical loops are essential to express the control structure
of any flowchart.
Iterative Statements
Logically Controlled Loops
The C-based programming languages include both pretest and posttest logically controlled loops that are
not special forms of their counter-controlled iterative statements.
The pretest and posttest logical loops have the following
forms:
Iterative Statements
User-Located Loop Control C, C++, Python, Ruby, and C# have unconditional
unlabeled exits (break).
Mechanisms Java and Perl have unconditional labeled exits (break
in Java, last in Perl).
In some situations, it is convenient for a Following is an example of nested loops in Java, in
programmer to choose a location for loop which there is a break out of the outer loop from the
nested loop:
control other than the top or bottom of the loop
body.
As a result, some languages provide this
capability.
A syntactic mechanism for user-located loop
control can be relatively simple, so its design is
not difficult. Such loops have the structure of
infinite loops but include user-located loop exits.
Iterative Statements
User-Located Loop
Control Mechanisms
C, C++, and Python include an
unlabeled control statement,
continue, that transfers control to
the control mechanism of the
smallest enclosing loop.
This is not an exit but rather a way
to skip the rest of the loop
statements on the current iteration
without terminating the loop
structure.
Unconditional Branching
Unconditional branching is when the programmer forces the execution of a program to jump to
another part of the program.
Theoretically, this can be done using a good combination of loops and if statements.
In fact, as a programmer, you should always try to avoid such unconditional branching and use this
technique only when it is very difficult to use a loop.
We can use “goto” statements (unconditional branch statements) to jump to a label in a program.
The goto statement is used for unconditional branching or transfer of the program execution to the
labeled statement.
Unconditional Branching
Fundamentals of Subprograms
A subprogram definition describes the interface to and the actions of the subprogram abstraction.
A subprogram call is the explicit request that a specific subprogram be executed. A subprogram is said to
be active if, after having been called, it has begun execution but has not yet completed that execution.
The
two fundamental kinds of subprograms,
1. procedures : set of commands executed in order
2. functions : set of instructions used for some computation
Subprograms
Fundamentals of Subprograms
A subprogram header, which is the first part of the definition, serves several purposes.
Second, if the subprogram is not anonymous, the header provides a name for the subprogram.
Third, it may optionally specify a list of parameters.
Consider the following header examples:
Local Variable
Subprograms can define their own variables, thereby defining local referencing
environments.
Variables that are defined inside subprograms are called local variables, because their
scope is usually the body of the subprogram in which they are defined.
variables can be either static or stack dynamic.
If local variables are stack dynamic, they are bound to storage when the subprogram
begins execution and are unbound from storage when that execution terminates.
Subprograms
There are several advantages of stack- dynamic the primary one being flexibility. It is
essential that recursive subprograms have stack- dynamic local variables.
Another advantage of stack dynamic locals is that the storage for local variables in an active
subprogram can be shared with the local variables in all inactive subprograms
The main disadvantages of stack- dynamic local variables are the following:
First, there is the cost of the time required to allocate, initialize (when necessary), and
deallocate such variables for each call to the subprogram.
Second, accesses to stack- dynamic local variables must be indirect, whereas accesses tostatic
variables can be direct.
Subprograms
The primary advantage of static local variables over stack- dynamic local variables is that
they are slightly more efficient— they require no run- time overhead for allocation and
deallocation.
Also, if accessed directly, these accesses are obviously more efficient. And, of course, they
allow subprograms to be history sensitive.
The greatest disadvantage of static local variables is their inability to support recursion.
Also, their storage cannot be shared with the local variables of other inactive subprograms.
Subprograms
Local Referencing Environments
In most contemporary languages, local variables in a subprogram are by default stack dynamic.
In C and C++ functions, locals are stack dynamic unless specifically declared to be static.
For example, in the following C (or C++) function, the variable sum is static and count is stack
dynamic.
Subprograms
Parameter- Passing Methods For example,
• consider a subprogram that takes two arrays of int
Parameter- passing methods are the ways in which values as parameters— list1 and list2.
parameters are transmitted to and/or from called • The subprogram must add list1 to list2 and return
subprograms. the result as a revised version of list2.
• The subprogram must create a new array from the
Semantics Models of Parameter Passing
two given arrays and return it.
Formal parameters are characterized by one of three • For this subprogram, list1 should be in mode,
distinct semantics models: because it is not to be changed by the subprogram.
(1) They can receive data from the corresponding actual • list2 must be inout mode, because the
subprogram needs the given value of the array and
parameter;
must return its new value.
(2) they can transmit data to the actual parameter; or • The third array should be out mode, because
(3) they can do both. there is no initial value for this array and its
These models are called in mode, out mode, and inout computed value must be returned to the caller.
mode, respectively.
Subprograms
Implementation Models of Parameter Passing
A variety of models have been developed by language designers to guide the implementation of the three
basic parameter transmission modes. In the following sections, we discuss several of these, along with
their relative strengths and weaknesses
Subprograms
Implementation Models of
Parameter Passing
1. Pass By Value
This method uses in-mode semantics.
Changes made to formal parameter do not
get transmitted back to the caller.
Any modifications to the formal parameter
variable inside the called function or method
affect only the separate storage location and
will not be reflected in the actual parameter
in the calling environment.
This method is also called as call by value.
Subprograms
2. Pass- by- Result
Pass- by- result is an implementation model for out- mode parameters.
When a parameter is passed by result, no value is transmitted to the subprogram.
Just before control is transferred back to the caller, the value of the formal parameter is transmitted back to
the actual parameter.
Abstract Data type (ADT) is a type (or class) for objects whose behavior is defined by a set of value and a
set of operations.
The definition of ADT only mentions what operations are to be performed but not how these operations will
be implemented.
It does not specify how data will be organized in memory and what algorithms will be used for
implementing the operations.
It is called “abstract” because it gives an implementation-independent view.
The process of providing only the essentials and hiding the details is known as abstraction.
The user of data type does not need to know how that data type is implemented, for example, we have been
using Primitive values like int, float, char data types only with the knowledge that these data type can
operate and be performed on without any idea of how they are implemented.
So a user only needs to know what a data type can do, but not how it will be implemented.
Abstract Data Types
Parameterized Abstract Data Types
It is often convenient to be able to parameterize abstract data types. For example, we should be able to
design a stack abstract data type that can store any scalar type elements rather than be required to write a
separate stack abstraction for every different scalar type.
Encapsulation Constructs
Encapsulation is a mechanism of wrapping the data (variables) and code acting on the data (methods)
together as a single unit.
In encapsulation, the variables of a class will be hidden from other classes, and can be accessed only through
the methods of their current class. Therefore, it is also known as data hiding.
Advantages of Encapsulation
Encapsulation hides the implementation of a program and hence easy to read and modify in the future
according to business requirements.
It allows us to deploy the updated code version wherever required, without requiring the whole program to
be restructured.
It secures the program by providing data hiding functionality.
Encapsulation promotes a modular way of programming making code resilient.
Encapsulation in C++
Encapsulation also lead to data abstraction or
hiding. As using encapsulation also hides the
data. In the above example the data of any of
the section like sales, finance or accounts is
hidden from any other section.
In the above program the variable x is made
private. This variable can be accessed and
manipulated only using the functions get() and
set() which are present inside the class. Thus
we can say that here, the variable x and the
functions get() and set() are binded together
which is nothing but encapsulation.
Encapsulation in C#
Encapsulation is implemented by using access specifiers. An access specifier defines the scope and
visibility of a class member. C# supports the following access specifiers −
1. Public
2. Private
3. Protected
4. Internal
5. Protected internal
Encapsulation in C#
Public Access Specifier
Public access specifier allows a class to expose its member variables and member functions to other functions and objects.
Any public member can be accessed from outside the class.
Private Access Specifier
Private access specifier allows a class to hide its member variables and member functions from other functions and objects.
Only functions of the same class can access its private members. Even an instance of a class cannot access its private
members.
Protected Access Specifier
Protected access specifier allows a child class to access the member variables and member functions of its base class. This
way it helps in implementing inheritance.
Internal Access Specifier
Internal access specifier allows a class to expose its member variables and member functions to other functions and objects
in the current assembly. In other words, any member with internal access specifier can be accessed from any class or
method defined within the application in which the member is defined.
Naming Encapsulations
Large programs define many global names; need a way to divide into logical groupings
A naming encapsulation is used to create a new scope for names
C++ Namespaces
• Can place each library in its own namespace and qualify names used outside with the namespace
• C# also includes namespaces
Java Packages
• Packages can contain more than one class definition; classes in a package are partial friends
• Clients of a package can use fully qualified name or use the import declaration
Ada Packages
• Packages are defined in hierarchies which correspond to file hierarchies
• Visibility from a program unit is gained with the with clause