programs: a set of operations working on certain data in a certain sequence.
Differences among languages are in the
chapter 4: data types that are built into languages
chapter 5: programmer-defined data types (encapsulated data types)
chapter 6: individual operation and sequence control
chapter 7: subprogram control
chapter 8: introduces inheritance (operations on encapsulated
data objects can be automatically derived)
It is important to differentiate between:
A data object has various attributes that define that object. The value that is bound to some of these attributes may change during runtime. Some of the most important of these include:
Examples of data objects are:
const int MAX = 30;
A data type is a class of data objects together with a set of operations for creating and manipulating them. Each language has a set of primitive data types built into the language. Each data type has a specification that is made up of
A data type also has an implementation, made up of
A program deals with particular data objects, but a programming language deals more commonly with data types and the operations provided for manipulating them.
Every programming language has a set of primitive (or elementary) data types that are built into the language. In addition, a language may provide facilities to allow the programmer to define new data types, such as C and Ada. In other words, there are two kinds of data types
such as characters, integers, real numbers, Booleans, etc.
such as arrays, records, character strings, etc.
An elementary data type is an elementary data objects plus operations. Elementary data objects may store only one value, i.e. integer, boolean, character.
sin(x) -> sin: float float
x = b -> =: integer x integer boolean
x + b -> +: float x float float
operations are often implemented via hardware, though many use some sort of algorithm
Implementation of Elementary Data Types
A declaration is a program statement commonly used to specify the name and type of data objects
Declarations of Operations: to specify the signatures of operations to the language translator
There are also type declarations. e.g.,
typedef struct{
int number;
char name[NAME_LEN+1];
} Part;
Purposes for Declarations
Each memory location contains some binary string. By that information alone, it is impossible to tell the type of the data object stored in that location. A computer could try to add two integers, whereas they may actually record two reals, leading to a garbage result.
Type checking is the process of ensuring that the arguments to an expression are of correct types. In other words, to ensure that each operation receives the proper number of arguments of the proper type. This may be done dynamically, but this requires that each data object stores its type, and that each time an operation is performed the type is checked. Most languages minimise dynamic type checking by doing it statically at compile time.
When are two types equivalent?
type alink = pointer to cell;
type blink = alink;
p, q : pointer to cell;
r : alink;
s : blink;
t : pointer to cell;
u : alink;
type student = record
name, address : string;
SSN : integer;
end;
type school = record
name, address : string;
enrollment : integer;
end;
On the other hand, if you define one type as an alias for another, you
probably want them to be the same.
Strong typing has been defined in different ways. We will
take it to mean the following:
A language is strongly typed if that language prevents you from applying an
operation to data for which it is not appropriate.
A related definition: A function f, with signature f : S -> R, is type safe if execution of f cannot generate a value outside of R
in C: 1 + 1.5
in C: (int)1.5
6.0 +15/8 = 7.0
6 +15.0/8 = 7.875
{ int X; X = 14; ...
Location for an object X is its L-value. Contents of that location is its R-value
Where did names L-value and R-value come from?
Consider: A = B + C;
Executing that statement requires:
1. Pick up contents of location B
2. Add contents of location C
3. Store result into address A.
For each named object in an assignment statement, its position on the right-hand-side of the assignment operator (=) is a ``content-of'' access, and its position on the left-hand-side of the assignment operator is an ``address-of'' access.
address-of then is an L-value
contents-of then is an R-value
Value, by itself, generally means R-value
Floating-Point Real Numbers: some languages prohibit testing for equality due to rounding errors. Usually exactly like the hardware, but not always; some languages allow accuracy specs in code (e.g., Ada):
type Speed is
digits 7 range 0.0..1000.0;
type Voltage is
delta 0.1 range -12.0..24.0;
Fixed-Point Real Numbers: for precision, floats are stored as integers with the location of the decimal point recorded, i.e.
23.45 = 2345 (2)
23.45 + 36.78 = 2345 (2) + 3678 (2)
23.456 + 36.78 = 23456 (3) + 36780 (3)
Advanatage is accuracy. The disadvantage is limited range and wasted memory.
Complex Numbers: sometimes provided, usually stored in two storage locations.
Rational Numbers: sometimes provided, a rational number is a number represented as a quotient of two numbers (i.e. LISP) Used to avoid roundoff errors. Often stored as unbounded length integers.
Enumerations: The user enumerates all of the possible values, which
are symbolic constants, i.e. type class is red, yellow, blue.
Usually stored as an integer, basic operations are the relational
operators (greater than, equal, e.t.c.), assignment, successor and
previous. The order is usually given by the order of their
declaration, though C can override this,
i.e. enum class Fresh=14, Soph=36, Junior=4, Senior=42
Design Issue: Should a symbolic constant be allowed to be in more than one type definition?
Examples:
Subrange Types An ordered, contiguous subsequence of another ordinal type.
Design Issue: How can they be used?
Examples:
type pos = 0 .. MAXINT;
subtype Pos_Type is
Integer range 0 ..Integer'Last;
Booleans: usually check for equality in one of two ways (a) if a particular bit is 0 or 1, (b) the value 0 represents false, and all other values represent true.
Usually stored as one memory storage unit. However some languages allow for many booleans to be collected into one unit. i.e. bit string (PL/I), packed array of boolean (Pascal).
Characters: Sometimes available individually, though sometimes only as a string. Sometimes languages do not specify a character set but simply use the basic set defined in the underlying hardware and operating system. Some do define a set (i.e. ASCII) but if the underlying machine does not support it, it must be emulated in software.