SlideShare ist ein Scribd-Unternehmen logo
1 von 132
Downloaden Sie, um offline zu lesen
PASCAL
LECTURE NOTES
DR. ALEJANDRO DOMINGUEZ
ING. EDGAR HERRADOR
FUNDACION ARTURO ROSENBLUETH
1993
INTRODUCTION
Programming languages are divided in special purpose languages and
general purpose languages.
Each special purpose language is intended for a particular application
area.
Pascal is probably the best, widely available, general purpose
programming language in the world at the present time, especially as a
vehicle for learning the principles of good programming. Pascal was
named after the 17th century French mathematician, and it is available
on almost every computer - from great machines to tiny
microprocessors.
Pascal has three main advantages over most other languages. These
advantages are:
Transparency: A program is said to be transparent if it is easy to read
and easy understand. Given a well-written Pascal program, it can easily
be seen what its intended effect is.
Efficiency: This concerns the size of programs and the speed at which
they run on the computer. To be efficient, a program should be small
and fast - it does not matter how long the Pascal source program is.
Security: After writing a program in Pascal, the computer, and in
particular the compiler, is able to spot mistakes. Because Pascal
programs are transparent, the programmer tends to make fewer
mistakes. So, in this context, security does not mean locking something
away where no-one can get at it; it means that not much is likely to go
wrong without being noticed.
This course is to show how to write Pascal programs which are
transparent, efficient and secure.
CHAPTER 1
Getting Started
1.1. The form of a program
A Pascal program has the form
PROGRAM n (output)
BEGIN
{ statements (Pascal instructions) };
END.
The first line of the program is called the 'program heading'. The rest of
the program is the 'program body'.
PROGRAM, BEGIN and END are 'reserved words'. This means that they
can be used only in the context they are intended. They cannot serve as
names.
To distinguish reserved words from names, upper case (capitals) letters
are used for reserved words and (mainly) lower case letters for names.
The letter "n" above is a program name invented by the programmer.
A name in Pascal is called a identifier: It may contain only letters and
digits and must start with a letter.
Some compilers regard only the first eight characters of an identifier to be
significant and ignore the rest.
An identifier must be something meaningful.
The identifier "output" within the program heading signifies that the
program will produce output at the terminal. This is not a reserved word.
In Pascal, successive statements are separated by semicolons. Notice that
the program finishes with a full stop.
1.2 Output
1.2.1 'writeln'
A line of output can be produced by a 'writeln-statement' of the following
form
writeln('...')
where the dots represent the sequence of characters to be printed. The
apostrophes are called 'string quotes' and a sequence of characters
enclosed between string quotes is called a 'string'.
Thus, for example, the program
PROGRAM Merry1 (output);
BEGIN
writeln('Merry Christmas')
END.
will print the message
Merry Christmas
The writeln-statement may produce various outputs as it can be seen in the
following examples:
writeln('this''ll work won''t it')---> this'll work won't it
writeln('Merry','Christmas') ---> MerryChristmas
writeln('Merry', 'Christmas') ---> MerryChristmas
writeln('Merry ', 'Christmas') ---> Merry Christmas
One writeln-statement produces all its outputs on one line. To produce
output on more than one line, more than one writeln-statement must be
used. The program
PROGRAM Merry2 (output);
BEGIN
writeln('Merry Christmas');
writeln('Happy New Year')
END.
will produce two lines of output
Merry Christmas
Happy New Year
The identifier "writeln" is the name of something known as a 'procedure'
and the strings supplied by the programmer are known as 'parameters'.
When a writeln-statement is activated one is said to be 'calling' the
procedure.
It is possible to call the procedure "writeln" with no parameters and then
its effect at run-time is to print nothing; it simply moves the cursor down
to the start of the next line.
The program
PROGRAM Merry3 (output);
BEGIN
writeln('Merry Christmas');
writeln;
writeln('Happy New Year')
END.
will produce three lines of output
Merry Christmas
Happy New Year
Thus in the above program the effect of the parameterless writeln-
statement is to produce a blank between "Merry Christmas" and "Happy
New Year".
1.2.2 'write'
A write-statement has the same form as a writeln-statement except that
"write" replaces "writeln" and at least one parameter must be supplied.
The effect at rub time is the same except that the current output line is not
terminated; output from successive write-statements appears on the same
line.
A writeln-statement with three parameters "a", "b" and "c"
writeln(a, b, c)
is equivalent to the two statements
write(a, b, c);
writeln
and these, in turn, are equivalent to the four statements
write(a);
write(b);
write(c);
writeln
1.3 Program layout
Certain layout conventions shall be adopted in what follows and the
programmers is advised to follow suit since they are a mayor contributory
factor towards transparency.
(a) Nothing precedes PROGRAM, BEGIN or END on a line.
(b) PROGRAM, BEGIN and END are aligned but information between
BEGIN and END (and, as it will be seen later, between PROGRAM and
BEGIN) is idented two or three spaces.
(c) A semicolon immediately follows the first of the two items it
separates.
(d) Two statements on the same line are separated by few spaces.
(e) A statement does not extend across one a line boundary (but this
constrain will be relaxed when statements get longer.
Because a semicolon separates one statement from the next, no semicolon
should follow a statement which precedes END. However, a semicolon at
this point is allowed and some people find that its inclusion simplifies the
task of inserting further statements at a later date.
In these lecture notes, no such superfluous semicolons will appear.
1.4 Comments
Pascal permits the inclusion of 'comments' within a program in order to
annotate it for the benefit of the human reader.
It is customary to insert a comment at the head of a program to describe
the function of the program and perhaps give such information as the
names of the authors and the date the program was last amended.
Any sequence of characters enclosed between braces, the curly brackets {
and }, is interpreted as a comment and has no effect upon the action of the
program.
A comment may also be set between the compound symbols (* and *). A
comment may appear at any point in the program at which a space would
be legal.
Here is an example of a program containing a comment.
PROGRAM Merry4 (output);
(* Prints Christmas and New Year messages *)
BEGIN
writeln('Merry Christmas');
writeln;
writeln('Happy New Year')
END.
CHAPTER 2
Think of a Number
2.1 Constants
A number is a particular example of a constant.
In Pascal numbers are of two types: 'integer' and 'real'.
Examples of integer constants (with no decimal point) are:
123 -1 0 4623784502 -7897999
Examples of real constants (with a decimal point) are:
10.0 -347.8216 3.1415926
The largest integer which can be represented is available in the form of a
predefined constant named "maxint".
All integers must be in the range -maxint and +maxint.
A typical value of "maxint" is 32767 (2^15 - 1).
On a small computer, the reals range from -10^40 to +10^40
approximately and about seven significant figures might be recorded.
There are two ways of representing real numbers: 'fixed point' form, as
above, and 'floating point' form. The later has the form
aEb
number a can be an integer or fixed point real value
number b must be an integer
letter E is interpreted as "times 10 to the power"
Some examples are:
fixed point floating point
-347.8216 -3.478216E2
0.00001 1E-5
7200000000.0 7.2E9
2.2 Expressions
Numeric data can be processed using 'operators' and 'brackets'. The
operators are:
+ represents addition
- represents subtraction
* represents multiplication
/ represents (real) division
These operators are applied from left to right at any one bracket level
subject to the fact that
* and / take precedence over + and -
Here are some examples
5 + 2 * 3 = 11 (integer)
(5 + 2) * 3 = 21 (integer)
9.7 - 14.82 = -5.12 (real)
10 / 5= 2.0 (real)
7 + 8.4 / 2.1 * 2 = 15.0 (real)
Arithmetic expressions may be supplied as parameters to "writeln" but,
unlike strings, they are not enclosed within string quotes.
The program
PROGRAM Recta1(output);
(* For a rectangle of given dimensions,
this program prints its area *)
BEGIN
writeln('A rectangle of length 3 cm and width 2 cm');
writeln('has area ', 3 * 2, ' sq cm')
END.
produces the output
A rectangle of length 3 cm and width 2 cm
has area 6 sq cm
2.3 User-defined constants
Constant declarations appear between the PROGRAM line and the
BEGIN, heralded by a single occurrence of the reserved word CONST.
A constant 'declaration' has the form
CONST
i1 = c1;
i2 = c2;
... ...
where i1, i2, ... are identifiers
and c1, c2, ... are constants
Notice that each declaration is followed by a semicolon.
An example is the following program.
PROGRAM Recta2 (output);
(* For a rectangle of given dimensions,
this program prints its area *)
CONST
length = 3;
width = 2;
BEGIN
write('A rectangle of length ', length, ' cm');
writeln(' and width ', width, ' cm');
writeln(' has area ', length * width, ' sq cm')
END.
Apart from spacing and some minor modifications, this program produces
the same output as the previous version. But there are some
improvements:
'Transparency': The relevance of each constant, and hence each
expression, is clearer.
'Modification': This program can be applied to a different rectangles more
easily than the previous version - the values are changed in the constant
definition. In the previous program, the entire program has to be scanned
in order to change every occurrence of each constant. The improved
program is not only easier to modify, it is safer - there is less chance of
making a mistake when making changes.
2.4 Formatted output
A field width can be specified for any parameter of "write" or "writeln".
If the field is too wide, the output is 'right-justified' and the field 'space-
filled' from the left.
If the field width specified for an arithmetic value is too small, it is
ignored and the minimum field width necessary is used. So if a field width
of 1 is supplied, no additional spaces will be output.
If the parameter of "write" or "writeln" is a string or an integer number,
the syntax for a formatted output must be of the form
write(parameter : fieldwidth)
or writeln(parameter : filedwidth)
If the parameter of "write" or "writeln" is a real number, the syntax for a
formatted output must be of the form
write(parameter : fieldwidth : decimalplaces)
or writeln(parameter : fieldwidth : decimalplaces)
Thus, the three statements
writeln('*', 7:1, ' ' :6, 423 :1, 6 :5);
writeln('*', 49 :8, 'Fred' :9);
writeln('*', 5.6789 :5:2)
produce the following output
*7bbbbbb423bbbb6
*bbbbbb49bbbbbFred
*b5.6
2.5 Variables
A 'variable' is an identifier which may be associated with different values
(but all of the same type) at different times during the execution of a
program.
Variable declarations appear between the constant declarations (if there
are any) and BEGIN, heralded by the single occurrence of the reserved
word VAR.
Variable declarations have the form
VAR
a1, a2, a3, ..., an : type1;
b1, b2, b3, ..., bm : type2;
... ... ... ... ...
where a's and b's are identifiers
and type1 and type2 are 'types'
For the present types are restricted to the types "integer" and "real". These
are said to be 'scalar' types and "integer" types are also known as 'ordinal'
type.
Integer variables are used for things which can only be whole numbers.
Real variables are used for things which may be fractional numbers.
Notice that a variable declaration introduces a variable but associates no
value with it - its value is said to be 'undefined'.
2.6 Input
On way of giving a value to a variable is to type a value when the program
is running and make the program give this value to the variable. Then it is
said that the program 'reads' the value.
Supplying data at run-time has the advantage that different runs of one
program utilize different data; there is no need to change the program.
If a program is to read a value from the terminal, the identifier "input"
must appear in the PROGRAM line along with "output", the two being
separated by a comma.
PROGRAM ... (input, output);
In Pascal, reading can be achieved by either of two statements: "read" and
"readln".
2.6.1 'read'
A read-statement has the form
read(v1, v2, ..., vn)
where v1, v2, ..., vn are variables, possible of different types
The program
PROGRAM NexAge (input, output);
(* Increments a supplied age by 1 *)
VAR
agenow : integer;
BEGIN
write('How old are you? ');
readln(agenow);
writeln('After your next birthday you will be ', agenow+1)
END.
reads a person's age and states the age next birthday.
When this program is run nothing will happen until the user types an
integer. The program will then respond with the appropriate output.
2.6.2 'readln'
"readln" is to "read" as "writeln" is to "write". The form is the same except
that no parameter need be supplied.
When "readln" is supplied with no parameters
readln
the program stops until it is typed the return-key (enter-key).
When "readln" is supplied with parameters
readln(a, b, ..., z)
is equivalent to
read(a, b, ..., z) + skip line
The program
PROGRAM PetShop1 (input, output);
(* Sums four integers typed one per line,
each possibly followed by text *)
VAR
pet1, pet2, pet3, pet4 : integer;
BEGIN
writeln('Type the number in stock of each of your ',
'four species');
writeln(' - one per line');
readln(pet1);
readln(pet2);
readln(pet3);
readln(pet4);
writeln('Total number of pets in stock is ',
pet1 + pet2 + pet3 + pet4 : 1)
END.
accumulates the total stock in a pet shop which offers four different types
of pet. Each number is read from a different line and anything typed after
the number is ignored.
The data could be typed in the form
7 cats
4 dogs
2 birds
1 fish
and only the numbers would be read.
CHAPTER 3
Doing Arithmetic
3.1 Assignment statement
An expression can be used to assign a value to a variable. A value may be
assigned to a variable by an 'assignment statement'. This has the form
v := e
where v is a variable,
e is an expression
and := is the 'assignment operator'
Expression e may be a type integer if variable v has type real but
otherwise variable v and expression e have the same type.
Assignment operator := is read as 'becomes'.
When an assignment statement is obeyed the expression on the right hand
side is evaluated and the resultant value assigned to the variable on the
left.
Any value previously associated with the variable is lost ('overwritten').
A variable retains a value assigned to it until it subsequently acquires a
different value, either by reading or by direct assignment.
Expression e may include variables in the same way that in can include
constants.
When a variable is encountered within an expression at run-time the
current variable is used. Any reference to an undefined value constitutes
an error.
Return to program "PetShop1", that one can be modified as follows
PROGRAM PetShop2 (input, output);
(* Sums four integers typed one per line,
each possibly followed by text *)
VAR
pet1, pet2, pet3, pet4, totpets : integer;
BEGIN
writeln('Type the number in stock of each of your ',
'four species');
writeln(' - one per line');
readln(pet1);
readln(pet2);
readln(pet3);
readln(pet4);
totpets := pet1 + pet2 + pet3 + pet4;
writeln('Total number of pets in stock is ',
totpets :1)
END.
More than one assignment may be made to the same variable.
Also, a variable may appear on both the left hand side an the right hand
side of the same assignment statement.
Both of these points are illustrated in the following program which prints
a number and its three successors together with their squares and
reciprocals.
PROGRAM SqrtReci (input, output);
(* Prints four consecutive integers together
with their squares and reciprocals *)
VAR
n: integer;
BEGIN
write('What is the starting value? ');
readln(n);
writeln;
writeln(' 2');
writeln(' n n 1 / n');
writeln(n :4, n * n :6, 1 / n :8:3);
n := n+1;
writeln(n :4, n * n :6, 1 / n :8:3);
n := n+1;
writeln(n :4, n * n :6, 1 / n :8:3);
n := n+1;
writeln(n :4, n * n :6, 1 / n :8:3)
END.
3.2 Arithmetic expressions
3.2.1 'Arithmetic operators'
The two operators +, -, * and / are applicable to integer and real operands.
There are two operators which are applicable only to two integer operands
and each produces an integer result.
DIV - integer division (gives the integer part of division).
MOD- modulo reduction (gives the remainder left by
integer division).
DIV and MOD have the same precedence as * and /; i.e., {* / DIV MOD}
are applied before {+ -}.
The first operand should be positive or zero and the second should be
positive.
Here are some examples.
15 DIV 7 = 2 15 MOD 7 = 1
7 DIV 15 = 0 7 MOD 15 = 7
6 DIV 6 = 1 6 MOD 6 = 0
The following program takes a 3-digit integer, introduced as a user
defined constant, and prints it backwards.
PROGRAM RevInt (output);
(* Reverses a positive three digit integer,
specified as a user-defined constant *)
CONST
n = 472;
VAR
hundreds, tens, units : integer;
BEGIN
hundreds := n DIV 100;
tens := (n MOD 100) DIV 10;
units := n MOD 10;
writeln(n, ' reversed is ', units :1, tens :1, hundreds :1)
END.
3.2.2 'Standard functions'
There are six functions which are applicable to real and integer operands
'x' (called parameters) and each produces a real result.
sin(x)sine of x. x must be in radians
cos(x) cosine of x. x must be in radians
exp(x) e to the power x. e = base of natural logarithms
= 2.7182818284...
ln(x) natural logarithm of x. x must be > 0
sqrt(x) square root of x. x must be >= 0
arctan(x) arc tangent of x. Its result is in the range from
-pi to +pi radians
One way of computing the value of pi to the maximum accuracy of your
machine is knowing that tan(pi/4)=1, thus pi= 4 * arctan(1):
PROGRAM Pi (output);
(* Compute the value of pi to the maximum accuracy *)
BEGIN
write('According to the computer the value of pi is ');
writeln(4 * arctan(1) :1:15)
END.
Pascal does not provide an operation of exponentiation; i.e., the operation
of raising any positive number to any power. But this operation may be
constructed by an application of functions "exp(x)" and "ln".
The expression
exp(b * ln(a))
gives the value of "a" raised to the power "b".
There are two functions which can supply an integer or a real result,
depending upon the type of parameter supplied.
abs(x) absolute magnitude of x; i.e., x becomes
positive
sqr(x)square of x; i.e., x * x
The function "sqr(x)" should always be used when x is an expression more
complicated than a single constant or variable, since Pascal evaluates
functions more slowly than multiplications and additions.
As an example consider the following program
PROGRAM triang(input, output);
(* This program computes the length of the hypotenuse of a
right-angled triangle, given the lengths of the other two sides,
as well as the sine, cosine and tangent of each of the two
no-right-angles. It also computes the value of the
no-right-angles *)
VAR
h, s1, s2, a1, a2 : real;
sin1, sin2, cos1, cos2, tan1, tan2 : real;
BEGIN
writeln;
writeln('The right-angled triangle is:');
writeln;
writeln(' ¦  ');
writeln(' ¦a1 ');
writeln('s1 ¦  h');
writeln(' ¦  ');
writeln(' ¦ a2  ');
writeln(' --------- ');
writeln(' s2 ');
writeln;
write('Enter length of side s1 = ');
readln(s1);
write('Enter length of side s2 = ');
readln(s2);
(* Start Computations *)
h := sqrt(s1 * s1 + s2 * s2); (* compute hypotenuse h *)
a1 := arctan(s2 / s1); (* compute angle a1 *)
sin1 := sin(a1); (* compute sine of a1 *)
cos1 := cos(a1); (* compute cosine of a1 *)
tan1 := sin1 / cos1; (* compute tangent of a1 *)
a2 := arctan(s1 / s2); (* compute angle a2 *)
sin2 := sin(a2); (* compute sine of a2 *)
cos2 := cos(a2); (* compute cosine of a2 *)
tan2 := sin2 / cos2; (* compute tangent of a2 *)
(* Write results *)
writeln;
writeln('The hypotenuse is = ',h :1:4);
writeln;
writeln('The angle a1 is = ',a1 :1:4, ' radians');
writeln('The sine of a1 is = ',sin1 :1:4);
writeln('The cosine of a1 is = ',cos1 :1:4);
writeln('The tangent of a1 is = ',tan1 :1:4);
writeln;
writeln('The angle a2 is = ',a2 :1:4, ' radians');
writeln('The sine of a2 is = ',sin2 :1:4);
writeln('The cosine of a2 is = ',cos2 :1:4);
writeln('The tangent of a2 is = ',tan2 :1:4)
END.
Two functions which map a real value onto an integer are
round(x) - rounds x to the nearest integer
trunc(x) - truncs x to a integer result
Here are some examples:
round(7.4) = 7 trunc(7.4) = 7
round(-7.4) = -7 trunc(-7.4) = -7
round(7.5) = 8 trunc(7.5) = 7
round(-7.5) = -8 trunc(-7.5) = -7
round(7.6) = 8 trunc(7.6) = 7
round(-7.6) = -8 trunc(-7.6) = -7
3.2.3 'Precision of reals'
Within the computer, integers are stored exactly but reals involve some
inherent error. This is because only certain number of significant figures
can be stored.
Suppose a decimal machine capable of storing four significant figures.
The expression 1/3 evaluated to four significant figures is 0.3333. The
expression 2 * (1 / 3) therefore produces 0.6666. The expression 2 / 3
evaluated to four significant figures is 0.6667. So two expressions which
are mathematically equivalent can produce different values.
CHAPTER 4
Being Choosy
4.1 If-statement
The if-statement exists in a full and a shortened form. The full form is
IF t THEN
s1
ELSE
s2
where t is a test
and s1 and s2 are any statements
Notice that no semicolons appear within the if-statement but a semicolon
will follow the if-statement (that is, after s2) if the if-statement is followed
by another statement.
When the statement is encountered at run-time the test t is made. If the test
holds then s1 is obeyed (and s2 is not); if the test does not hold then s2 is
obeyed (and s1 is not). I either case control then passes to the statement
next in sequence after the if-statement.
Rather than choose which of two statements to obey it is often wished to
make a simpler decision - whether to obey one statement or not.
An abbreviated form of the if-statement is available for this.
IF t THEN s
where t is a test
and s is any statement
If test t holds, s is obeyed; if not, s is not obeyed. In either case control
passes to the statement next in sequence after the if-statement.
Tests can include the relational operators
< less than
<= less than or equal to
> greater than
>= greater than or equal to
= equal to
<> not equal to
and these have the lowest precedence of all the operators.
The following program, which determines the smallest of three supplied
integers, includes both forms of if-statements.
PROGRAM minim3(input, output);
(* Determines the smallest of three integers *)
VAR
n1, n2, n3, min : integer;
BEGIN
write ('Type three integers: ');
readln(n1, n2, n3);
IF n1 < n2 THEN
min := n1
ELSE
min := n2;
IF n3 < min THEN
min := n3;
writeln('The smallest of these is = ', min :1)
END.
4.2 Case-statement
A case-statement provides a multi-way selection based on a range of
values. The usual form is
CASE e OF
v1 : s1;
v2 : s2;
. . .
vn ; sn
END (* CASE *)
where e is an expression of some ordinal type, say t,
v1, v2, ..., vn are distinct constants of type t
and s1, s2, ..., sn are statements
The only ordinal type it has been met is "integer" so, for the present, "t"
must be integer.
At run-time, only one of the 'limbs' s1, s2, ..., sn will be obeyed.
The 'selector' e is evaluated and, assuming it produces one of the values
v1, v2, ..., vn, the statement labeled with the appropriate value is selected.
The selector must evaluate to one of the supplied case labels; failure to do
so constitutes an error.
Use of a case-statement is appropriate when selection is
governed by an ordinal expression whose values are few and
known.
The following program uses a case statement to print the 'name' of a
supplied digit.
PROGRAM Digname1 (input, output);
(* Names a supplied digit *)
VAR
digit : integer;
BEGIN
write('Give me a digit ');
readln(digit);
write('This is ');
CASE digit OF
0 : writeln('zero');
1 : writeln('one');
2 : writeln('two');
3 : writeln('three');
4 : writeln('four');
5 : writeln('five');
6 : writeln('six');
7 : writeln('seven');
8 : writeln('eight');
9 : writeln('nine')
END (* CASE *);
END.
In the above program, it has been assumed that the cases listed are the
only possible ones.
Now assume that the number 23 is typed. This number is not a digit and,
when running the program, 23 in never encounter.
Pascal standard does not indicate what should happen if a value other than
those listed is encountered. For some compilers it will result in a run-time
error; for others, no statement is executed.
Some implementations of Pascal include, as a nonstandard extension, an
"else" case.
This is illustrated in the following program.
PROGRAM Digname2 (input, output);
(* Names a supplied digit *)
VAR
digit : integer;
BEGIN
write('Give me a digit ');
readln(digit);
write('This is ');
CASE digit OF
0 : writeln('zero');
1 : writeln('one');
2 : writeln('two');
3 : writeln('three');
4 : writeln('four');
5 : writeln('five');
6 : writeln('six');
7 : writeln('seven');
8 : writeln('eight');
9 : writeln('nine')
ELSE
writeln('no a digit')
END (* CASE *);
END.
One case limb may be prefixed by more than one case-label.
The next program illustrates this. This program converts number grades to
letter grades.
PROGRAM Grades (input, output);
(* Convert number grades to letter grades *)
VAR
grade : integer;
BEGIN
write('Enter the numeric grade: ');
readln(grade);
write('The letter grade is ');
CASE grade DIV 10 OF
9, 10 : writeln('A');
8 : writeln('B');
7 : writeln('C');
6 : writeln('D');
0..5 : writeln('F')
ELSE
writeln('no recorded')
END (* CASE *)
END.
4.3 Compound statement
Only one statement may be supplied as a case limb or following THEN or
ELSE but it often wished to supply more than one.
Pascal provides a means of bracketing statements together so that they
become one 'compound statement'.
BEGIN and END are used as statement brackets.
This is illustrated in the following program.
PROGRAM Order (input, output);
(* Order two given integer numbers
being the second the greatest *)
VAR
first, second, temp : integer;
BEGIN
write('Type two integer numbers: ');
readln(first, second);
IF first > second THEN
BEGIN
temp := first;
first := second;
second := temp;
END;
writeln('In order they are: ',first, ' ', second)
END.
4.4 Nested conditionals
A case limb or the statement following THEN or ELSE may itself be
conditional or contain a conditional statement.
The general form of a nested if-statement is the so-called "cascading" IF-
THEN-ELSE
IF ... THEN
...
ELSE
IF ... THEN
...
ELSE
. . .
IF ... THEN
...
ELSE
. . .
This form is illustrated in the following program
PROGRAM PosNeg (input, output);
(* Decides if a given real number is
either positive, negative or zero *)
VAR
n : real;
BEGIN
write('Enter a real number : ');
readln(n);
IF n > 0 THEN
writeln('The number is positive')
ELSE
IF n < 0 THEN
writeln('The number is negative')
ELSE
writeln('The number is zero')
END.
A nesting of the form
IF t1 THEN
IF t2 THEN
s1
ELSE
s2
is not recommended since it is less easy to follow.
When IF immediately follows THEN it can be difficult (for the human
reader) to sort out which ELSE goes with which THEN. This is
particularly so when one of the if-statements has no else-part.
For the Pascal compiler the ELSE will be associated with the second
THEN. However, this may not be apparent for the human reader. This is
called the "trailing problem".
There are two ways to improve transparence in this context.
One, often the best, is to rewrite this section of program so that the
problem does not arise.
Two, is to use statement brackets to explicitly associate the ELSE with its
intended THEN. BEGIN and END may be used to enclose a single
statement. The earlier schema can be transformed into either
IF t1 THEN
BEGIN
IF t2 THEN
s1
END
ELSE
s2
to associate the ELSE with the first THEN or
IF t1 THEN
BEGIN
IF t2 THEN
s1
ELSE
s2
END
to associate the ELSE with the second THEN.
On the other hand, a case-statement can be nested within an if-statement:
IF ... THEN
CASE ... OF
. . .
END (* CASE *)
ELSE
. . .
CHAPTER 5
Character by Character
5.1 Char type
By characters it is meant the letters of the alphabet (uppercase and
lowercase), the digits 0-9, and other special characters that are used for
punctuation, abbreviation, and so on.
A third scalar type is "char". It comprises all the characters available in the
set of characters used by the computer.
The most common sets are ASCII (American Standard Code for
Information Interchange) and EBCDIC (Extended Binary Coded Decimal
Interchange Code).
ASCII set will be assumed now on.
As with the real and integer types, it can be defined constant and variables
of type "char". Here are some character constant definitions:
CONST
space = ' ';
dot = '.';
zero = '0';
A character constant is a string of length 1.
A variable of type "char" is declared as:
VAR
x : char;
Variable x can take as its value any character in the set available.
When a value is read into a character variable only one character (string of
length 1) is read from the input stream.
When a character is output, unless a field width greater than 1 is specified,
no extra spaces will be printed; the character will occupy only one
character position.
This is illustrated in the next program.
PROGRAM Reveword (input, output);
(* Reverses any four letter word *)
VAR
c1, c2, c3, c4 : char;
BEGIN
write('Please type a four-letter word: ');
readln(c1, c2, c3, c4);
writeln('Reversed, this is: ', c4, c3, c2, c1)
END.
The ASCII set form an ordered sequence - this is called the 'lexicographic'
order:
Associated with each character is an 'ordinal number', its position in the
lexicographical order.
The first character has ordinal number 0, the second one ordinal number 1,
and so on.
Any data type whose values form a countable, ordered sequence is called
an 'ordinal' type.
That is why "integer" was described as an ordinal type (but "real" was
not). Thus characters can be used as case-statement selectors:
PROGRAM GiveName (input, output);
(* Prints one of four names given the initial *)
VAR
initial : char;
BEGIN
write ('What is your initial? : ');
readln(initial);
write('Hi ');
CASE initial OF
'B' : writeln('Brian');
'A' : writeln('Amanda');
'F' : writeln('Frank');
'C' : writeln('Christine')
END (* CASE *)
END.
Since the ASCII set is an ordered sequence, the relational operators can be
applied to any to operands of (the same) ordinal type.
Consequently, it can be assumed that relations such as
'A' < 'Z'
'D' > 'C'
'7' >= '4'
'9' < 'A'
are true.
Be clear in mind of the difference between the characters '0', '1', ..., '9' and
the integers 0, 1, ..., 9.
Characters can be assigned to character variables, but integers cannot be
assigned to characters variables. On the other hand, two integers can be
multiplied, two characters cannot be multiplied.
5.2 Standard functions
Since there is an order established for the characters, each character
except the first has a predecessor, and each one except the last has a
successor.
Predecessors and successors are delivered by two functions:
pred(x) - predecessor of char variable x
succ(x) - successor of char variable x
For example
pred('c') = 'b' succ('c') = 'd'
The following program reads a character and prints five consecutive
characters centred on the supplied character.
PROGRAM Charact5 (input, output);
(* Prints five consecutive characters centred on a
supplied character *)
VAR
ch : char;
BEGIN
write('Give me a character: ');
readln(ch);
writeln('Five characters centred on ', ch, ' are ',
pred(pred(ch)), pred(ch), ch,
succ(ch), succ(succ(ch)) )
END.
Two functions map between characters and their ordinal numbers. These
ones are
chr(x) - delivers a character given its ordinal
number x
ord(x) - delivers the ordinal number of a supplied
character x
Thus, the position in the alphabet of a lower case letter represented by a
variable "xx" is given by
ord(xx) - ord('a') + 1
and the letter at position "yy" in the alphabet (if "yy" is an integer variable
with a value in the range 1 to 26 is given by
chr(ord('a') + n -1)
The functions "ord(x)", "succ", and "pred" can be applied to items of any
ordinal type.
5.2 Text files
A file composed of characters and end-of-line markers is called a 'text'
file.
The two identifiers "input" and "output", used in the program heading, are
the names of the 'standard' text files, one to be used for reading and one
for writing.
In chapter 13 the whole aspect of files in detail shall be examined in
detail. For the moment it will be seen how a Pascal program can use
external, non-standard, text files not associated with the terminal.
There are four aspects of these files:
1. All external files with which the program is to communicate must be
named in the program heading.
2. Non-standard text files must be declared within the program as
variables type "text".
3. Before a non-standard file can be used it must be initialized either for
reading or for writing. A file "f" is initialized for reading by one of the
following procedures (depending on the Pascal implementation)
STANDARD PASCAL TURBO PASCAL
reset(f) assign(f, 'filename.$$$');
reset(f)
In both cases the procedure "reset" can be applied to the file several times
during the execution of a program and, each time, the file concerned is
initialized for reading from the beginning.
A file "g" is initialized for writing by one of the following procedures
(depending on the Pascal implementation)
STANDARD PASCAL TURBO PASCAL
rewrite(g) assign(g, 'filename.$$$');
rewrite(g)
In both implementations, file "f" must already exist (because it cannot
otherwise be read).
The file "g" need no to exist before the program is run. If it does exist, it
will be overwritten; if it does not, and empty file "g" will be automatically
created when the program is about to be run.
In Turbo Pascal a file must be closed after reading from or writing to it
using the statement "close(f)"
4. In both implementations, to read from or to write to a non-standard file,
files "f" or "g" must be supplied as the first parameter to the input/output
procedure.
For example, two characters would be read from a text file "f" by a
statement of the form
read(f, c1, c2) or readln(f, c1, c2)
and two characters would be written to a text file "g" by a statement of the
form
write(f, c1, c2) or writeln(f, c1, c2)
An example of the above four aspects is the following program, which is a
modification of program Reveword of section 5.1.
This new program reads the four-letter word from a file, say
"inrever4.$$$", and produces the reversed copy in another file, say
"outreve4.$$$".
PROGRAM Reverse4 (infile, outfile);
(* Reverses any four letter word *)
VAR
infile, outfile : text;
c1, c2, c3, c4 : char;
BEGIN
(* Read from file inrever4.$$$ *)
assign(infile, 'inrever4.$$$');
reset(infile);
readln(infile, c1, c2, c3, c4);
close(infile);
(* write to file outreve4.$$$ *)
assign(outfile, 'outreve4.$$$');
rewrite(outfile);
writeln(outfile, 'Reversed word: ', c4, c3, c2, c1);
close(outfile)
END.
CHAPTER 6
Round and Round Until You Are Finished
6.1 Loops
Computers are often wanted to repeat some process several times. When a
program obeys a group of statements several times, it is said to be
'looping'.
Loops are of two types: If it is known how many times it is wished to
repeat the loop the situation is said to be 'deterministic'; if not, it is 'non-
deterministic'.
6.2 'For-statement'
A deterministic loop is implemented by a 'for-statement'.
There are two forms of this statement: incremental (forward) for-statement
and decremental (backward) for-statement.
The general form of an incremental for-statement is
FOR v := e1 TO e2 DO
s
where v is a variable of some ordinal type, say t, e1 and e2
are expressions of type t
and s is any statement.
Some remarks must be made:
1. Expressions e1 and e2 are the minimum and maximum values of
variable v, respectively.
2. At the moment of starting the for-statement, variable v is initialised to
the value of expression e1 and its value compared with the value of
expression e2. In general, at the end of each loop variable v takes
successive values
e1, succ(e1), succ(succ(e1)), ..., e2
and its new value is compared with the value of e2. Thus, in some sense, v
is a control variable of the number of loops or repetitions.
3. Variable v is updated automatically and the programmer must make no
attempt to change its value within the loop.
4. Upon termination of the loop, variable has no value at all.
5. If e2 < e1, the loop body s is not obeyed at all; otherwise the body is
executed a number of times equal to
ord(e2) - ord(e1) + 1
Each execution of the loop is called an 'iteration'.
The general form of a decremental for-statement is
FOR v := e1 DOWNTO e2 DO
s
where v is a variable of some ordinal type, ast t, e1 and e2
are expression of type t
and s is any statement.
It might be noted here that 'DOWNTO' is one word, not two, there is no
space in it.
If e1 < e2 the loop body s is not obeyed at all; otherwise the loop body is
obeyed a number of times equal to
ord(e1) - ord(e2) + 1
For each successive iteration of the loop body the control variable, v,
takes successive values
e1, pred(e1), pred(pred(e1)), ..., e2
The following program uses both forms of for-statements to print the
alphabet forwards and backwards.
PROGRAM Alphabet(output);
(* Prints the alphabet forwards and backwards *)
VAR
xx : char;
BEGIN
FOR xx := 'a' TO 'z' DO
write(xx);
writeln;
FOR xx := 'z' DOWNTO 'a' DO
write(xx)
END.
A loop body need not refer to the control variable.
The following program raises two numbers to a specified power and the
control variable merely governs the number of iterations.
In this program it is also shown that a loop body may comprise several
statements if they are bracketed to form a compound statement.
PROGRAM Numston(input, output);
(* Raises two numbers x and y to a non-negative power *)
VAR
x, xx, y, yy : real;
n, power : integer;
BEGIN
write('Please give me two numbers: ');
readln(x, y);
write('To what power would you like it raised? ');
readln(n);
(* Initialize auxiliary variables *)
xx := 1;
yy := 1;
(* Start computations *)
FOR power := 1 TO n DO
BEGIN
xx := xx * x;
yy := yy * y
END;
writeln(x:1:4, ' raised to the power ', n:1, ' is ', xx :9:4);
writeln(y:1:4, ' raised to the power ', n:1, ' is ', yy :9:4)
END.
When one loop occurs within the body of another, the loops are said to be
'nested'.
This is illustrated in the following program which writes to a file the
multiplication tables from 1 to a given number n.
PROGRAM Multable(input, f);
(* Writes to file MULTIPLI.$$$ the multiplication
tables from 1 to a given number n *)
CONST
max = 10;
VAR
f : text;
i, j, n : integer;
BEGIN
write('Input the number of the maximum multiplication
table: ');
readln(n);
assign(f, 'MULTIPLI.$$$');
rewrite(f);
writeln(f, 'MULTIPLICATION TABLES UP TO ', n:1);
FOR i := 1 TO n DO
BEGIN
writeln(f);
writeln(f, 'TABLE OF ', i :2);
writeln(f);
FOR j := 1 TO max DO
writeln(f, i :2, ' * ', j :2, ' = ', i*j :3)
END;
close(f)
END.
6.3 While-statement
Pascal provides two non-deterministic loops: a while-statement and a
repeat-statement.
In this section is studied the while-statement.
The general form of this statement is
WHILE t DO s
where t is a test
and s is any statement
The test (t) is made 'prior' to each execution of the loop body (s).
If the test proves false, control leaves the while-statement and passes to
the next in sequence after the while-statement.
If the test holds true, the loop is obeyed and the process repeated until the
test eventually proves false.
If test is false upon first entry, the loop body is not entered at all.
The body of a while-loop need not be executed
So, here are some guidelines for using WHILE.
A while-loop is appropriate when it is not known how many
times it is wanted the loop body obeyed
and
it may be 'not at all'
The loop body (s) may be composed of either one or several statements. In
the last case, it must be bracketed to form a compound statement.
Three steps must be performed in every program that uses a while-loop.
These are
- initialize the loop-control (implicit in test t) variable before the loop is
reached
- test the loop-control variable before each loop repetition
- update the loop control variable in the loop body (s)
If the first step is omitted, the initial test of the loop control-variable will
be meaningless. If the last step is omitted, the loop control variable value
cannot change and the loop will execute "forever".
The above facts are illustrated in the following program which finds and
prints the time required to double a given amount of money.
PROGRAM Banker(input, output);
(* Finds and prints the time required to double a given amount of
money *)
VAR
year : integer;
depos, balanc, rate, intrst, double : real;
BEGIN
write('Enter the deposit amount : ');
readln(depos);
write('Enter the interest rate as a decimal fraction: ');
readln(rate);
(* Initialize year, balanc, and double *)
year := 0;
balanc := depos;
double := 2 * depos;
(* Recompute balanc until the initial deposit amount is
doubled *)
WHILE balanc < double DO
BEGIN
year := year + 1;
intrst := balanc * rate;
balanc := balanc + intrst
END;
writeln('Deposit amount is doubled after ', year:1, 'years');
writeln('New balance is ', balanc:1:2)
END.
6.4 Comparison of while-loops and for-loops
It has been said that a while-loop is anon-deterministic one, however, as
shown in the next example, a while-loop can also be used to implement a
counting loop.
Consider the following while-loop used to find the sum of the first "n"
integers, and the respective for-loop
WHILE-LOOP FOR-LOOP
sum := 0; sum := 0;
nxtint := 1; FOR nxtint := 1 TO n DO
WHILE nxtint <= n DO sum := sum + nxtint;
BEGIN
sum := sum + nxtint;
nxtint := nxtint + 1
END;
The most obvious difference between the loops is that the while-loop is
longer.
This illustrates that the while-loop should not be used to implement a
counting loop.
The for-loop is easier to write and should be used when the number of
loop repetitions need can be determined before loop entry.
The main reason for the extra length of the while-loop involves the
manner in which the loop-control variable "nxtint" is manipulated:
- "nxtint" is set to a initial value of 1 (nxtint := 1)
- "nxtint" is tested before each loop repetition (nxtint <= n)
- "nxtint" is updated during each loop repetition
(nxtint := nxtint + 1)
Although these three steps are implicit in the for-loop, they must be
specified explicitly when the while-loop is used.
If the loop-control variable is not initialised properly before the while-
statement is reached, the loop-repetition test will be meaningless.
If the loop control variable is not updated, the loop-repetition test will
always be true and the loop will not be exited (infinite loop).
6.5 Repeat-statement
The second non-deterministic loop is the repeat-statement.
The general form is
REPEAT
s1;
s2;
...
sn;
UNTIL t
where t is a test
and s1, s2, ..., sn are any statements
The test (t) is made 'after' each execution of the loop body (s1, s2, ..., sn).
If the test holds true, the loop is terminated and control passes to the
statement next in sequence after the repeat-statement.
If the test proves false, control returns to the start of the loop body and the
whole process is repeated until the test eventually holds true.
Once the loop is under way, a while-loop and a repeat-loop are equivalent.
The difference is upon the first entry.
With WHILE, the test is made 'before' the first execution of the loop body;
with REPEAT, the test is made 'after' the first execution.
The body of a repeat-loop is obeyed at least once
Here are guidelines for using REPEAT.
A repeat-loop is appropriate when it is not known how many
times it is wanted the loop body obeyed
but
it must be 'at least once'
More than one statement can be included within the body of a repeat-loop
without being bracketed between BEGIN and END.
The above facts are illustrated in the following program which computes
the smallest Fibonacci number greater than some specified bound.
The first two terms of the Fibonacci sequence are 0 and 1. Each
successive term is the sum of the previous two.
The program insists that the bound be greater than 1 and it must therefore
be computed 'at least one' new term. So REPEAT must be used.
PROGRAM Minfib (input, output);
(* Computes the smallest Fibonacci number which exceeds a
specified bound *)
VAR
bound, term1, term2, term3 : integer;
BEGIN
write('Specify the bound: ');
readln(bound);
IF bound < 1 THEN
writeln(' *** bound is too small ***')
ELSE
BEGIN
term3 := 1;
term2 := 0;
REPEAT
term1 := term2;
term2 := term3;
term3 := term2 + term1
UNTIL term3 > bound;
writeln('Smallest Fibonacci number greater',
' than ', bound :1, ' is ', term3 :1)
END
END.
CHAPTER 7
True or False?
7.1 Boolean types
Boolean data types are those which can only take values "true" or 'false".
These are called 'Boolean values'.
This category of data includes constants, variables, functions and
expression of logic type. Hence a test following IF, WHILE and UNTIL is
particular case of a 'Boolean expression'.
The two values ("true" and "false") applied to Boolean data types for an
ordered set where "false" precedes to "true". "false" has ordinal number 0
and "true" has ordinal number 1. Consequently
"false" < "true"
Boolean values can be written to a text file but not read from one.
7.2 Boolean case selector
A case-statement can emulate an if-statement. The test becomes a Boolean
selector and the two statements become limbs prefixed by "true" and
"false".
CASE t OF
true : s1;
false : s2
END (* CASE *)
is equivalent to
IF t THEN s1 ELSE s2
7.3 Boolean constants
A user-defined constant may have type Boolean.
For example, if "const1" and "const2" are two constants taken values
"true" and "false", respectively, then they are declared as:
CONST
const1 = true;
const2 = false;
A common use of user-defined constants is to control the selection of
output statements, particularly during the development of a program.
7.4 Boolean variables
A Boolean variable can take either of the two values "true" and "false" and
can acquire one of these values directly
VAR
b1, b2 : boolean;
. . .
b1 := true;
b2 := false;
or via a Boolean expression
VAR
negative, posdisc, factorfound,
usersaysno, dhasreachedn : boolean;
. . .
negative := digit < 0;
posdisc := disc > 0;
factorfound := n MOD d = 0;
usersaysno := reply = 'n';
dhasreachedn := d = n
In the following program is applied these facts. This program prints two
supplied three-letter words in alphabetical order.
PROGRAM Two3lett (input, output);
(* Prints two supplied three-letter words in alphabetical order *)
VAR
a1, a2, a3, b1, b2, b3 : char;
ab : boolean;
BEGIN
writeln('Type two three-letter words, one per line:');
readln(a1, a2, a3);
readln(b1, b2, b3);
IF a1 < b1 THEN ab := true
ELSE
IF a1 > b1 THEN ab := false
ELSE
IF a2 < b2 THEN ab := true
ELSE
IF a2 > b2 THEN ab := false
ELSE
ab := a3 <= b3;
CASE ab OF
true : writeln(a1, a2, a3, ' ', b1, b2, b3);
false : writeln(b1, b2, b3, ' ', a1, a2, a3)
END (* CASE *)
END.
A Boolean variable can obviously be used to record the result of a test
made within a loop.
7.5 Boolean functions
There are three standard functions which produce a Boolean result.
odd(x) - it becomes "true" if x is odd and "false"
otherwise. x must be integer
eoln(f) - it becomes "true" if there is no more
information to be read in the current line
of file f and "false" otherwise. When file
is "input", the parameter f may be omitted
eof(f) - It becomes "true" if there is no more
information to be read in file f and "false"
otherwise. When file is "input", the
parameter "f" may be omitted
The following program copies file "FILE1.$$$" onto file "FILE2.$$$".
PROGRAM Copyfile (f1, f2);
(* Program to copy "FILE1.$$$" onto "FILE2.$$$".It says the
number of character and if the number of lines is either
even or odd *)
VAR
f1, f2 : text;
ch : char;
licount, chcount : integer;
BEGIN
writeln;
writeln('COPYING "FILE1.$$$" to "FILE2.$$$" ...');
(* Initialize file f1 and file f2 *)
assign(f1, 'FILE1.$$$');
assign(f2, 'FILE2.$$$');
reset(f1);
rewrite(f2);
(* Initialize counter of lines and counter of characters *)
licount := 0;
chcount := 0;
(* Start copy *)
REPEAT
(* Making copy of each line *)
REPEAT
(* Counting characters *)
chcount := chcount + 1;
(* Making copy of each character *)
read(f1, ch);
write(f2, ch)
UNTIL eoln(f1);
(* Counting lines *)
licount := licount + 1;
UNTIL eof(f1);
(* Display results *)
writeln('COPY FINISHED');
write('The number of lines is');
IF odd(licount) THEN
writeln(' odd and equals ', licount:1)
ELSE
writeln(' even and equals ', licount:1);
write('The number of characters is');
IF odd(chcount) THEN
writeln(' odd and equals ', chcount:1)
ELSE
writeln(' even and equals', chcount:1);
(* Close files *)
close(f1);
close(f2)
END.
7.6 Boolean operators
If a Boolean expression is preceded by the operator
NOT
its value is 'inverted'.
If "b" has the value "true" then "NOT b" is "false"; if "b" has the value
"false then "NOT b" is "true".
Boolean operators can be combined using two Boolean operators
AND
OR
If b1 and b2 are Boolean
b1 AND b2 is "true" only if b1 'and' b2 are both "true"
b1 OR b2 is "true" if either b1 'or' b2 is "true" (or both
are "true")
Each of these operators has different precedence. Their precedence
'decreases' in the order
NOT { highest precedence }
AND { same precedence as DIV MOD * / }
OR { same precedence as + - }
In order to avoid errors when programming, bracketing must be used.
Then, if b1 and b2 are Boolean
b1 OR b2 must be written as (b1) OR (b2)
b1 AND b2 must be written as (b1) AND (b2)
NOT b1 must be written as NOT (b1)
All brackets are necessary because of the relative priorities of operators.
7.7 Set membership
Pascal allows the construction of 'sets'.
Square brackets, [ and ], are used as 'set constructors' and members are
separated by commas.
All members of a set must have the same type, and this must be an ordinal
type (and, hence, not "real"). This is called the base type of the set.
A set member may be represented by any expression of the base type.
Here are some examples
[1, 2, 3, 5, 7, 11] { set of integers }
['a', 'e', 'i', 'o', 'u'] { set of characters }
[i+1, ord('A')-1] { set of integers }
A short hand notation is available for a contiguous group of set members.
The set
[4, i-2, i, 6, i+1, i-1, i-4, i+3, 5, i+2]
can be written
[4..6, i-2..i+3, i-4]
Multiple occurrences of a value are equivalent to a single occurrence of
that value. The set
['C'..'H', 'W', 'E', 'F'..'K', succ('A')]
is the set
['C'..'K', 'W', succ('A')]
Set membership can be detected with the relational operator
IN
The right hand operand must be a set and the left hand operand must be an
expression whose type is the same as the base type of the set. The operator
yields "true" only if the value of the left hand operand is currently a
member of the right hand set.
For example the best way to check that an integer is in the range 1 to 9 is
with a set:
IF digit IN [1..9] THEN ...
One final note: sets are 'implementation dependent'. Both the maximum
size of a set and the range of ordinal numbers that set members may
possess vary from one computer to another.
CHAPTER 8
A Matter of Routine
8.1 Some routine definitions and concepts
Procedures and functions are called routines.
A routine is essentially a small piece of program with an associate name.
Routines offer two benefits:
1) Transparency is improved when the purpose of a group of statements is
indicated by a single.
2) Duplication is avoided when one routine is "called" several times.
A procedure is a routine which causes some change. Consequently, a procedure
call constitutes a statement.
A function is a routine which causes no change but computes a value.
Consequently, a function call constitutes an expression.
Some standard procedures have already been found (write, writeln, read,
readln, etc), as well as some functions (sin, cos, sqrt, odd, etc).
Pascal allows to extend the number of routines available by declaring user's
own.
Routines must be declared between the variable declarations (if there are any)
and the BEGIN of the program body.
8.2 Procedures
A simple procedure has the basic form
PROCEDURE p;
BEGIN
s1; s2; ...; sn
END (* p *);
where p is the procedure name
and s1, s2, ..., sn are the statements (these constitutes the
procedure body
The procedure can be "called" from the main program by simply quoting its
name. This gives the "procedure call statement". When a procedure is called,
the statements of the procedure body are obeyed and the control returns to the
statement following the call.
As an example of the use of procedures consider the program to copy on file
onto other (see Program Copyfile in Chapter 7). This program consists of
several actions:
Initialize files 1 and 2 (file 1 to be read and file 2 to be written)
Initialize counter of lines and counter of characters of file 1
Start copy from file 1 to file 2
Making a copy of each line from file 1 to file 2
Making a copy of each character from file 1 to file 2
Display results
Close files
The complete program might have the following structure, where the actions
are declared as procedures:
PROGRAM Copyfilp (f1, f2);
(* Program to copy "FILE1.$$$" onto "FILE2.$$$". It says the
number of character and if the number of lines is either even
or odd *)
VAR
f1, f2 : text;
ch : char;
licount, chcount : integer;
(* ***************************************************** *)
PROCEDURE Inifiles;
(* Initialise file f1 and file f2 *)
BEGIN
assign(f1, 'FILE1.$$$');
assign(f2, 'FILE2.$$$');
reset(f1);
rewrite(f2)
END; (* initialization of files *)
(* ***************************************************** *)
PROCEDURE Inilicha;
(* Initialize counter of lines and counter of characters *)
BEGIN
licount := 0;
chcount := 0
END; (* initialization of counters *)
(* ***************************************************** *)
PROCEDURE Copychar;
(* Copy each character from file 1 to file 2 *)
BEGIN
REPEAT
(* Counting characters *)
chcount := chcount + 1;
(* Making copy of each character *)
read(f1, ch);
write(f2, ch)
UNTIL eoln(f1)
END; (* copy of characters *)
(* ***************************************************** *)
PROCEDURE Copyline;
(* Making copy of each line from file 1 to file 2 *)
BEGIN
REPEAT
copychar;
licount := licount +1
UNTIL eof(f1)
END; (* copy each line *)
(* ***************************************************** *)
PROCEDURE Copyfile;
(* Start copy form file 1 to file 2 *)
BEGIN
copyline
END; (* copy of lines *)
(* ***************************************************** *)
PROCEDURE Dispresu;
(* Display results *)
BEGIN
writeln('COPY FINISHED');
write('The number of lines is');
IF odd(licount) THEN
writeln(' odd and equals ', licount:1)
ELSE
writeln(' even and equals ', licount:1);
write('The number of characters is');
IF odd(chcount) THEN
writeln(' odd and equals ', chcount:1)
ELSE
writeln(' even and equals', chcount:1)
END; (* display results *)
(* ***************************************************** *)
PROCEDURE Clofiles;
(* Close files *)
BEGIN
close(f1);
close(f2)
END; (* close files *)
(* ***************************************************** *)
BEGIN (* Main Program *)
writeln;
writeln('COPYING "FILE1.$$$" onto "FILE2.$$$" ...');
Inifiles;
Inilicha;
Copyfile;
Dispresu;
Clofiles
END.
Notice in this program that one procedure may call another. The only
restriction is that the declaration of a procedure must precede its calls.
A procedure may even call itself. It is then said to display "recursion" but this is
beyond the scope of the present lecture notes.
8.3 Localized information
It have been seen that a program can contain declarations specifying entities
which may be used by procedures which are declared within the program and
by statements of the program body.
The same applies to procedures. A procedure declaration may contain its own
declarations.
Any entity declared within a procedure may be used by any procedure declared
within the procedure and by statements of the procedure body.
Declarations within a procedure appear between the PROCEDURE line and the
BEGIN of the procedure body and are subject to the same rules of order as in
the main program.
An entity declared within a procedure is said to be "local" to the procedure.
An entity declared in the main program is said to be "global".
Storage space for local variables is allocated at run-time when a procedure is
entered and released when the procedure is exited. So, even if two variables in
different procedure have the same name, they will refer to different storage
locations at run-time.
It is good practice to declare variables as locally as possible. This reduces the
possibility of their corruption in other part of the program. As an example of
the above remarks consider the following program.
PROGRAM Locvar(input, output);
(* Program to shows the use of local and global variables *)
CONST
k = 10; (* this is a global constant *)
VAR
ch : char; (* this is a global variable *)
(* ***************************************************** *)
PROCEDURE Writchar;
CONST
m = 5; (* this a local constant *)
VAR
i, km : integer; (* these are local variables *)
BEGIN
km := k - m;
writeln('The character ', ch,' repeated ', k-m,' times is:');
FOR i := 1 TO km DO
writeln(ch)
END;
(* ***************************************************** *)
BEGIN (* MAIN PROGRAM *)
writeln;
write('Type any character: ');
readln(ch);
writchar;
readln
END.
8.4 Functions
The fundamental difference between a function and a procedure is that a
function call constitutes an "expression" because a function "delivers" a "result"
whereas a procedure call constitutes a "statement" and no value is associated
with the call.
A function is a suitable form for a routine when one is interested in only one
value computed by the routine and the routine produces no "side effects".
A routine is said to cause a side effect if it produces any non-local change.
A function with side effects is undesirable because functions are used in
expressions and a program con be hard to follow if evaluation of a expression
causes no-local changes.
In Pascal, a function may deliver a result of any ordinal type (boolean, char,
integer), of type real, on of any other type defined by the user (these are defined
in future chapters).
A function declaration differs from a procedure declaration in three respects:
1. -FUNCTION replaces PROCEDURE.
2. The type of the result delivered by the function is quoted
(preceded by a colon) before the closing semicolon of the
function heading.
3. Within the function body, there must be at least one
assignment statement with the function identifier on the
left hand side.
As an example consider the following program for raising a number x to an
integer power n.
PROGRAM Raisxton (input, output);
(* Raises a number a to en integer power n *)
VAR
x : real;
n : integer;
(* ********************************************* *)
FUNCTION xtothen : real;
VAR
xsquared, p : real;
power : integer;
BEGIN
If n = 0 THEN
xtothen = 1
ELSE
BEGIN
xsquared := sqr (x)
IF odd (n) THEN
p := x
ELSE
p := 1;
FOR power := 1 TO n DIV 2 DO
p := p * xsquared;
xtothen := p
END
END (* to then n *) ;
(* ********************************************* *)
BEGIN (* main program *)
write('Please give me a number: ');
readln(x);
write('To what power would you like it raised: ');
readln(n);
writeln(x, ' raised to the power ', n :1, ' is ', xtothen);
readln
END.
In order to give more examples illustrating the use of functions, consider the
following two programs
PROGRAM Insuranc (input, output)
(* Categorizes an age into one of five groups *)
VAR
age : integer;
(* **************************************************** *)
FUNCTION groupforage : char;
BEGIN
CASE age DIV 5 OF
3: groupforage := 'A';
4, 5: groupforage := 'B';
6..9: groupforage := 'C';
10..12: groupforage := 'D'
ELSE
groupforage := 'F
END; (* case *)
END; (* group for age *)
(* **************************************************** *)
BEGIN (* main program *)
write('Supply an age: ')
readln(age);
writeln('Insurance group is: ', groupforage);
readln
END.
PROGRAM Word3fns (input, output);
(* Prints two supplied three-Letter words in alphabetical order *)
VAR
a1, a2, a3, b1, b2, b3 : char;
(* ************************************************** *)
FUNCTION abinorder : boolean;
BEGIN
IF a1 < b1 THEN
abinorder := true
ELSE
IF a1 > b1 THEN
abinorder := false
ELSE
IF a2 < b2 THEN
abinorder := true
ELSE
IF a2 > b2 THEN
abinorder := false
ELSE
abinorder := a3 <= b3
END; (* a b in order *)
(* ************************************************** *)
BEGIN (* main program *)
writeln('Type two three-Letter words, one per line:');
readln(a1, a2, a3); readln (b1, b2, b3);
CASE abinorder OF
True : writeln (a1, a2, a3, ' ', b1, b2, b3);
false: writeln (b1, b2, b3, ' ' , a1, a2, a3)
END; (* CASE *)
readln
END.
CHAPTER 9
Routine Information
9.1 Transference of parameters
A program may transfer information to a procedure or obtain it from it.
Assume, for the moment, that a value is going to be passed to a procedure. As
an example, consider the following program having a procedure inside it
exhibiting the result in a Boolean expression, as for example "yes" or "not"
instead "true" or "false". Notice in this program that the Boolean value
"booleanvalue" is a formal parameter used as a variable into the procedure.
PROGRAM Eor (input, output);
(*Simulates the "exclusive or" operation *)
VAR
a, b, eo : boolean;
inta, intb : integer;
(* ********************************************** *)
PROCEDURE Yesno (booleanvalue : boolean );
(* Procedure to exhibit a boolean value *)
BEGIN
CASE booleanvalue OF
true : write ('YES');
false: write ('NOT')
END (* CASE *)
END; (* Yesno *)
(* ********************************************** *)
BEGIN (* Main program *)
REPEAT
write ('Enter two integer values, 0 is no: ');
readln (inta, intb);
a := true;
IF inta = 0 THEN
a := false;
b := true;
IF intb = 0 THEN
b := false;
(* Eco of the input values *)
write ('You input a ');
yesno (a);
write (' and a ');
yesno (b);
writeln;
(* Process and prints out an eor b *)
eo := (a AND NOT b) OR (b AND NOT a );
write ('The exclusive or of these ones is: ');
yesno (eo);
writeln
UNTIL false;
readln
END.
In general, a list of parameters gives the local names of the parameters as well
as their types. These are called "formal parameters" of the procedure:
PROCEDURE Byexample (i,j: integer; maybe:
boolean; b,c,g: real).,
Notice that the formal parameters are grouped by types.
When a procedure is used, the correct number of parameters must be given as
well as their corresponding types.
9.2 Value and variable parameters
In the example given in the preceding section, a value was transferred to a
procedure. But it is also frequent to transfer a value in the inverse way.
Pascal distinguishes two types of parameters:
value parameters: transfer values to a procedure
Variable parameters: transfer values from a procedure
Consider the following program:
PROGRAM Cubevalu (input, output);
(* Shows a value parameter *)
VAR
test : integer;
(* ********************************************** *)
PROCEDURE Cube (number : integer);
(* computers the cube of a given number *)
BEGIN
number := number * number * number;
writeln ('The cube of the number is: ', number)
END; (* Cube *)
(* ********************************************** *)
BEGIN (* Main program *)
writeln;
write ('Enter an integer value: ');
readln (test);
writeln ('The test value is: ', test);
cube (test);
writeln ('Now the value of test is: ', test);
readln
END.
The above program calls a procedure having a value parameter.
The cube of 3, which is 27, is given when the program is run with 3 is given as
input, but when the procedure has finished the value of "test" is still 3.
Therefore, if a procedure modifies a value parameter then only its own
temporary copy is modified.
The above program has modified its own local copy, called "number", but
"test" has not been modified.
Consider now the following modification of the above program:
PROGRAM Cubevari (input, output);
(* Shows a variable parameter *)
VAR
test : integer;
(* ********************************************** *)
PROCEDURE Cube (VAR number : integer);
(* Computers the cube of a given number *)
BEGIN
number := number * number * number;
writeln ('The cube of the numbers is: ', number);
END;
(* ********************************************** *)
BEGIN (* Main program *)
write ('Enter an integer value: ');
readln (test);
writeln ('The test value is: ',test);
cube (test);
writeln ('Now the test value is: ',test);
readln
END.
The reserved word "VAR" in the list of parameters specifies that "number" is a
variable parameter.
When the procedure modifies "number", the variable "test" is also modified.
This is an important difference.
A mixed group of value and variable parameters con be represented as follows.
PROCEDURE ZAMP (VAR a,b: integer., x: real., VAR
booby: boolean)
Here x is a real value parameter. The other ones are variable parameters.
For the case of functions, these may take parameters, they are always value
parameters.
As an example consider the following two programs using functions, which in
turn use value parameters.
PROGRAM Powers (input, output);
(* Given x, y, m and n, the program forms
x^m, y^n, (x^n)^m, (y^m)^n *)
VAR
x, y : real;
m, n : integer;
(* ********************************************* *)
FUNCTION powered (x : real; n : integer) : real;
VAR
i : integer;
p, xsquared : real;
BEGIN
IF n = 1 THEN
powered := x
ELSE
BEGIN
xsquared := sqr (x);
IF odd (n) THEN
p := x * xsquared
ELSE
p := xsquared;
FOR i := 2 TO n DIV 2 DO
p := p * xsquared;
powered := p
END
END; (* powered *)
(* ********************************************* *)
BEGIN (* program body *)
writeln('Give me two real numbers and two positive
integers: ');
readln(x, y, m, n);
writeln(x:1:2, ' raised to the power ', m:2, ' = ',
powered (x,m):1:2);
writeln(y:1:2, ' raised to the power ', n:2, ' = ',
powered (y,n):1:2);
writeln(x:1:2, ' raised to the power ', n:2,'
all raised to the power ', m :2, ' = ',
raised powered (x,n), m):1:2);
writeln (y:1:2, ' raised to the power ', m :2,
' all raised to the power ', n :2, ' = ',
powered (powered (y,m), n):1:2);
readln
END.
9.3 Forward references
It was stated at the end of section 8.2 that the declaration of a procedure must
precede its calls. Pascal provides a relaxation of this rule: A "routine heading"
must be declared before the routine is called but its "body" may be declared
later (but in the same block of procedures). The declaration of the heading
takes the form of a "forward reference". The routine heading is presented but
its body is replaced by
forward;
When its body is declared later, it is preceded by an abbreviated heading. Only
the routine identified appears following either PROCEDURE or FUNCTION.
No mention is made of any parameters, nor in the case of a function, nor the
type of the function.
In order to illustrate the above remarks, suppose procedures A and B are given
as shown next:
PROCEDURE A (a,b: integer);
BEGIN (* A *)
END; (* A *)
PROCEDURE B (x,y : real);
BEGIN (* B *)
A
END; (* B* )
Since A is defined first, it can be called from B., however, B may not be called
from A. According to the remarks given in order to make B callable from A,
two changes must be made in the procedures as written:
I) The heading line of procedure B, with the reserved word "forward" and a
semicolon appended, is written before the definition of procedure A.
II) The other change is in the actual heading line that accompanies procedure
B; it is simple written
PROCEDURE B;
With no indication of the parameters. No other change is made in procedure B.
Therefore the above procedure must be written as follows:
PROCEDURE B (x,y: real); forward;
PROCEDURE A (a,b: integer);
BEGIN (* A *)
END; (* A *)
PROCEDURE B;
BEGIN (* B *)
END; (* B *)
CHAPTER 10
Give it a Name
10.1 Introduction: types resumed
In the preceding chapters it has been studied "real"; "integer", "boolean" and
"char" types.
The types "real", "integer" and "char" can be written to and read from a text
file.
Boolean types can be written to a text file but not read from one.
"Integer", "boolean" and "char" types form an ordered set. This means that they
can be used for selection in a case-statement or as an index in a for-loop.
For any ordered type the following functions are well defined:
succ (x) successor of variable x
pred (x) predecessor of variable x
For example:
succ (3) = 4;
pred ('q') = 'p'
succ (false) = true;
succ (true) gives an error
Pascal allows to define user-defined types. In subsequent chapters it shall be
seen how data can be grouped in different ways; in this chapter it shall be learnt
how to define new types to represent scalars (single items).
There are two classes of user-defined scalar types: "subrange" types and
"symbolic" types. Both play a mayor role in improving the compile-time
security of a program, both contribute to program efficiency and symbolic
types in particular make significant contribution to a program transparency.
A series of type definitions may appear between the constant declarations (if
there are any) and the variable declarations (if there are any), heralded by the
reserved word TYPE. Thus a "type definition" has the form.
TYPE
i = t;
where i is an identifier
and t is a type.
Thus the order of declarations within any program is.
Constants, Types, Variables, Procedures and functions.
10.2 Subrange types
A variable of ordinal type, boolean, char, integer and symbolic (this will be
studied in the next section) can be restricted to a subrange. The variable is then
said to have a subrange type but inherits all the properties of its "host" type.
Any attempt to give a subrange variable a value outside its permitted range
constitutes an error. Notice that subranges or type "real" are not allowed.
A subrange type is denoted by the upper and lower bounds separated by two
dots. These bounds must be constants and the ordinal number of the lower
bound must not exceed the ordinal number of the appear bound.
Here are some subrange types.
1.. maxint
'A'..'Z'
-1..17
Subrange types may be defined in terms of user defined constants (see
examples below).
Subrange types allow the user to check the sensible use of variables. From the
"problem domain" the user decides what range of values should be sensible for
each variable and specify this range in the declaration of the variable. Any
attempt to assign a value outside the expected range will be prevented.
Using subranges the user helps the computer to detect his or her mistakes.
"Minimal subranging" should always be the aim.
As examples, consider the subranges that should have been used in some
previous examples.
I) An age cannot be negative and is unlikely to exceed, say, 120:
CONST
maxage = 120;
VAR
agenow: 0..maxage;
II) For any practical box, the length of each side must exceed 0:
VAR
length, width, depth: 1..maxint;
III) In the program which asks for initials A,B,C, or F the minimal subrange is
A to F:
VAR
initial: 'A'..'F'
IV) If a program ask for a digit it is more convenient the following
implementation:
TYPE
digits = 0..9;
VAR
digit : digits
PROCEDURE Name (d: digits);
V) Within a function which raises a real number to a positive power "n", the
parameter "n" cannot be negative and so should be constrained to the natural
numbers:
TYPE
naturals = 0..maxint;
VAR
m,n: naturals;
FUNCTION Powered (x: real; n: naturals): real;
On the other hand, subrange types provide a valuable protection against
programming errors and can also be used to detect data entry errors.
Obviously programs which "crash" when given bad input are not to be
encouraged so, for input data validation, it is often better to use range types to
read values and then assign these values to subranges variables only when it is
known that the values are in range. For example to real a digit, it could be used
two variables:
VAR
d: 0..9;
dtyped: integer;
And then read values until one is in range:
REPEAT
write ('please type a digit ' );
readln (dtyped)
UNTIL dtyped IN [0..9];
d: = dtyped
Of course, even this is not completely safe because an execution error will
result if anything other than an integer is typed.
10.3 Symbolic types
A symbolic type (or "enumerated" type as it is often called) is an ordered type.
This type is user-defined according to the results or values expected.
A symbolic type is denoted by a bracketed list of user-defined names. For
example:
TYPE
rainbow = (red, orange, yellow, green, blue, violet);
Where the type rainbow has six given values. In this example:
ord (red) = 0
ord (orange) = succ (red) = 1
Variables of type "rainbow" can be created:
VAR
pallet: rainbow;
A symbolic type can be used as a limb in a case-selector, or as index in a for-
loop.
In the above example, elements of the type "rainbow" can be assigned to
variables of the same type or compared among them, they also can be
transferred as parameters in procedures or functions.
Unfortunately, as was said before, symbolic type cannot be written to or read
from files. Thus the value "red" is not the chain of characters "red", it is simply
"red". However, it can be written ord (red) which is 0, and can be printed out
chains for the values of type "rainbow" making an appropriate procedure.
The above remark is illustrated in the following example. In this example is
presented the use of a symbolic type which represents the months of the year.
The programs asks for input a month number and outputs the month name.
There are several ways for implementing the program, but the example
illustrates a problem when using symbolic types. For the "char" type, the
function
chr (integer value)
is opposite to function
ord (character value)
As it was said, function "ord" can be used for symbolic types, however there is
not opposite to it in symbolic types. This program shows how to construct the
opposite to "ord" for symbolic types: unord (integer) must be the opposite to
ord (month).
PROGRAM Months (output);
(* Shows the conversion of elements of symbolic type: an integer is
transformed to a month and the month is displayed *)
TYPE
month = (jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov,
dec);
numonth = 1..12;
VAR
testmonth : month;
(* ********************************************** *)
PROCEDURE Givemonth (Thismonth : month);
(* Displays the full month name *)
BEGIN
writeln;
write ('This month is ');
CASE thismonth OF
Jan : writeln (' January ');
Feb : writeln (' February ');
Mar : writeln (' March ');
Apr : writeln (' April ');
May : writeln (' May ');
Jun : writeln (' June ' );
Jul : writeln (' July ');
Aug : writeln (' August ');
Sep : writeln (' September ');
Oct : writeln (' October ');
Nov : writeln (' November ');
Dec : writeln (' December ');
ELSE
writeln('not a month')
END; (* CASE *)
writeln
END;
(* ********************************************** *)
FUNCTION Ordmonth (imonth : numonth): month;
(* Converts an ordered integer to a month type *)
VAR
domonth : month;
index : numonth;
BEGIN
domonth := jan;
FOR index := 2 To imonth DO
domonth := succ(domonth);
ordmonth := domonth
END;
(* ********************************************** *)
PROCEDURE Takemonth (VAR Thismonth : month);
VAR imonth : numonth;
BEGIN
writeln;
write ('Enter the number 1..12 of a month: ');
readln (imonth);
Thismonth := ordmonth (imonth)
END;
(* ********************************************** *)
BEGIN (* Main program *)
REPEAT
Takemonth (testmonth);
givemonth (testmonth);
UNTIL false
END.
Subranges of symbolic types can be defined, for example with the type
"month":
TYPE
month = (jan, feb, mar, apr, may, jun, jul, aug, sep, oct,
nov, dec);
Subranges are created inside the "type" declaration itself, or in the "type"
declaration of a contained block.
halfore: jan .. jun;
halfore: jul .. dic:
CHAPTER 11
File it
11.1 Review of text files
As a data structure, a "file" is an ordered collection of related data items,
usually stored in external memory, for input to or output by a program; that is
information can be read from the file and/or written to the file.
The files used in Pascal programs up to this point have been "text files", whose
components are characters and these characters are organized into lines.
The predefined file type "text" is a standard type identifier used to declare text
files. The standard system files "input" and "output" associated with the
standard input (keyboard) and output (screen) devices are examples of text
files, and in Chapter 5. user-defined text files were described. The predefined
procedures "readln", "writeln", and "eoln" may be used only with text files.
Pascal also supports nontext files, whose components may be of any type,
simple or structured, except that they may not be of file type. Although
attention in this section is restricted to text files, much of the discussion also
applies to the other types of files considered in subsequent sections.
The principal rules governing the use of text files in Pascal programs as
discussed in Chapter 5 may be summarized as follows:
1. Program heading. It is good practice to include the names of all
files used in a program (including the standard text files input and
output) in the file list of the program heading.
2. Declaration. Each user-defined file must be declared as a file
variable in the declaration part of the program. For text files, the
predefined type identifier "text" can be used to specify the types of file
variables.
3. Associating file variables with actual files: In Pascal, before a file can
be used for input or output in a program, it must be associated with a disk file
by calling the predefined procedure "assign" in a statement of the form.
assign (file-variable, file-name);
4. Opening files for input. Each file from which data is read must first be
opened for input with the predefined procedure "reset" in a statement of the
form.
reset (file-variable);
Each such procedure call results the data pointer to the beginning of
the specified file. (The standard system file "input" need not be opened
for input.)
5. Each file to which data values are to be written must first be opened
for output. For text files, this can be done by using the predefined
procedure "rewrite" in a statement of the form.
rewrite (file-variable);
6. File input: Information can be read from a text file by using the
predefined procedures read and readln in the forms
read (file-variable, input-list)
readln (file-variable, input-list)
If file-variable is omitted, values are read from the standard system
file "input".
7. File output: Output can be directed to a text file by using the
predefined procedures write and writeln in the forms.
write (file-variable, output-list)
writeln (file-variable, output-list)
If file-variable is omitted, values are written to the standard system
file "output".
8. Closing files: In Pascal, after output to a file is completed, the file
should be closed by calling the predefined procedure "close" with a
statement of the form.
close (file-variable)
Failure to do so may result in the loss of data values because they
may not be transferred from the output buffer to the file.
9. Copying files: The contents of one file cannot be copied to another
file by using an assignment statement of the form "file- variable-1:= file-
variable-2". Rather the components must be copied one at a time.
10. Files as parameters: Formal parameters that represent files must
be variable parameters. This is a consequence of Rule 9, since value
parameters require copying the values of the corresponding actual
parameters.
11.2 Nontext files
While text files are frequently used in programming applications, "nontext file"
are sometimes more convenient.
Data written to a nontext file are transcribed, bit by bit, in exactly the same
form that they have within the computer. This has several advantages over text
files.
The first advantage is speed. Because there is no need to make conversions
from one form to another, the reading and writing are much faster.
A second advantage is a wider range of types that may be written to a file or
read from it.
Only characters, integers, and real numbers may be read from a text file; it can
be printed only these three types and boolean variables. However, anything that
can be represented within the computer can be written to or read from a nontext
file.
Nontext files have some disadvantages, too. The cannot be printed because
they are not in a printable (i.e., character) form. Similarly, they cannot be
created by an editor as a text file is. There are also certain restrictions on the
reading and writing that will be considered later in this section.
The above disadvantages suggest the uses for nontext files. It might no want to
have the output printed or displayed on the screen when the output is simply
used as the input for another (or the same) program: As already seen in Chapter
2 the output of the compiler is the input for the loader. Such output is not given
in a readable (that is, readable by humans) form.
Now let consider their declaration and use. In order to declare such a file, it is
used
VAR
filename: file of type;
or alternatively,
TYPE
typename = file of type;
VAR
filename: typename;
The "type" here can be almost any type: the simple types, arrays (chapters 12
and 13), or record (chapter 14) types. The only restriction is that it may not be
a file type or a record type with a file type component.
For example, the declarations
TYPE
file1 = file of integer;
file2 = file of char;
file3 = file of boolean;
VAR
f1 : file1;
f2 : file2;
f3 : file3;
are valid definitions of files.
It can be written to these files and read from them in much the same way as
with text files. Nevertheless, there are some differences, centering around the
fact that nontext files are not organized into lines as text files are. Thus, the
procedures readln and writeln and the function eoln cannot be used with
nontext files. The remaining functions and procedures relating to input and
output-reset, rewrite, read, write, and eof-are used in much the same way as
they were with text files.
While the types "text" and "file of char" might appear to be equivalent, there
are significant differences. The declaration
VAR
FileA : file of char;
does not declare FileA to be a text file; it is imply a nontext file containing only
characters. It is nor organized into lines: so we cannot use readln, writeln, on
eoln. Furthermore, a write statement will not convert numeric or boolean
values into strings of characters; nor will a read statement convert a string of
numeric character into an integer or real value. If it is given the command
READ
(FileA, x) or write (FileA, x)
With x declared to be anything other than a character type, it would result in an
error.
as an example of the use of nontext files, consider the following program:
PROGRAM filesrw (data, output);
(* This program creates a file of reals and
writes data to it and read data from it *)
VAR
data: FILE OF real;
value, square1, square2, root1, root2 : real;
count : integer;
BEGIN
assign(data, 'data.$$$');
(* write data to file *)
rewrite(data);
FOR count := 1 TO 10 DO
BEGIN
value := count;
square1 := sqr(value);
root1 := sqrt(value);
write( data, value, square1, root1)
END;
(* read data from file and display them to VDU *)
reset(data);
WHILE NOT eof(data) DO
BEGIN
read(data, value, square2, root2);
writeln(value :6:2, square2 :8:2, root2 :6:2)
END;
readln
END.
CHAPTER 12
Line up
12.1 One-dimensional arrays
So far, real and integer variables have been used for representing just one value
reach one. However there are a lot of situations for which a program must have
a list of variables of the same type represented by one only identifier.
In a mathematical presentation using many variables, subscripted variables are
often used; for example, x1, x2, x3,..., x [100]. Since anything cannot be
written above or below the line in programming languages, Pascal uses a
somewhat different notation. In Pascal, the notation is
x [1], x[2], x[3],..., x[100]
This is called an "array". More specifically, a "one-dimensional array" is finite
sequence of variables all of the same type and all identified by the same name.
One variable of an array is distinguished from another by its "subscript" or
"index", which is the value of an expression given within brackets and
following the array identifier.
In general, a subscripted (or indexed) variable has the form
identifier [expression]
The identifier is subject to the normal restrictions of identifiers; in particular,
there may be no space within it. Nevertheless, there may be one or more spaces
between the identifier and the left bracket, between the left bracket and the
expression, or between the expression and the right bracket.
The variables used above may be declared by (if they are of integer type)
VAR
x: ARRAY [1..100] OF integer
An alternative way of declaring the above array is by a named type-(that is, by
first declaring a type, which is then used to declare the variable.). Thus, it
might have.
TYPE
arraytype = ARRAY [1..100] OF integer;
VAR
x: arraytype;
"Type declarations" must precede variable declarations and follow constant
declarations.
Pascal requires named, rather than anonymous, types when passing arrays as
parameters.
A subscripted variable refers to a single storage location in the array and,
therefore, is used in much the same way as a simple variable. For example;
x [1] := 5;
list[7] := x[1] + y[7];
temp := list[7]
read (array [4])
While arrays allow us to define hundreds or thousands of variables with a
single declaration, their greatest advantage lies in the evaluation of the
subscript. It is not necessary to have a constant within the declared subscript
range. Whatever expression is within the brackets is evaluated, the result is the
subscript.
As example, suppose that
a[1] = 5, a[2] = 1, a[3] = 3, a[4] = 2, a[5] = 0,
b[0] = 4, b[1] = 2, b[2] = 3, b[3] = 1,
i = 3, j = 2
Then
a[1] = a[3] = 3,
b[j-1] = b[2-1] = b[1] = 2,
a[i+j] = a[3+2] = a[5] = 2,
a[i-j+1] = a[3-2+1] = a[2] = -1,
a[b[1]] = a[b[3]] = a[1] = 5,
b[a[j]] = b[a[2]] = b[-1] is not defined
a[b[a[j]+1]] = a[b[a[2]+1]] = a[b[0]] = a[4] = 2
It is this evaluation of the subscript that makes arrays so useful. With the added
facility of arrays the problem of reading a list of numbers and writing it in
reverse order is quite simply. This is show for a list of exactly 10 numbers in
the following program.
PROGRAM Readreve (input, output);
(* Reads a list of 10 integers and prints them in reverse order *)
TYPE
numarraytype = ARRAY [1..10] OF integer;
VAR
num : numarraytype;
index : integer;
BEGIN
writeln ('Give a list of 10 integers: ');
FOR index :=1 TO 10 DO
read (num[index]);
(* write the number in reverse order *)
writeln ('The reversed list is: ');
FOR index :=10 DOWNTO 1 DO
writeln (num[index]);
readln
END.
Arrays can sometimes be accessed in their entirety, rather than one component
at a time, in assignment statements or parameter passing. For example, if "a"
and "b" are declared identically, say
TYPE
realarray = ARRAY [1..25] OF real;
VAR
a,b: realarray;
Then
a: = b
is a valid assignment.
Similarly, if the following declarations are give
TYPE
arraytype = ARRAY[1..25] OF real;
VAR
a,b : arraytype;
and the procedure P parameter
VAR
c: arraytype;
Then the procedure P may be called by P (a) or P(b). When passing an entire
array, both the formal parameter and the actual parameter must be declared
using the same "named" type.
As an example, consider the following program
PROGRAM Findmax (input, output);
(* Shows the passing of arrays as a parameter*)
TYPE
demoray = ARRAY [1..4] OF integer;
VAR
one, two : demoray;
max, index : integer;
(* ********************************************** *)
PROCEDURE Takearray (VAR inarray : demoray);
(* An array is input *)
VAR
i : integer;
BEGIN
writeln ('Input 4 values for an array: ');
FOR i :=1 TO 4 DO
read (inarray [i]);
writeln
END;
(* ********************************************** *)
PROCEDURE Obtmax (sweeparray : demoray;
VAR value, position : integer);
(* Sweeps sweeparray in order to find its maximum value
as well as its position *)
VAR
i:integer;
BEGIN
value := sweeparray[1];
position := 1;
FOR i := 2 TO 4 DO
IF Sweeparray[i] > value THEN
BEGIN
value := Sweeparray[i];
position := i
END;
END;
(* ********************************************** *)
BEGIN (* Main program *)
writeln ('Find the maximum value of two arrays');
takearray (one);
takearray (two);
obtmax (one, max, index);
writeln ('The maximum of the first array is: ',max,
' at the index ', index);
obtmax (two, max, index);
writeln ('The maximum of the second array is: ', max,
' at the index ', index);
readln
END.
As it can be seen in the above program am array is passed as a variable
parameter. Procedure Takearray uses an array as a variable parameter since it
must return the array with its new values. Procedure obtmax uses a value
parameter; but it was not necessary. However, it is better to use a variable
parameter when using arrays. If a value parameter is used with arrays, the
computer must waste time and space to create the copies when a procedure is
called. Therefore
Always pass arrays as variable parameters
On the other hand, Pascal does not permit the following procedure or function
heading:
PROCEDURE Findmax (VAR arrent: ARRAY [1..10] OF
integer, big, where, : integer);
12.2. Sorting
Consider now the problem of sorting a list of n numbers according to a
sequence of increasing values. The program is going to be written in such a
way it does not use unnecessary memory; therefore it will contain a unique
array (one-dimensional, real and having x as name) where one element is going
to be reordered each time.
The method begins searching for in the array the lowest number and
exchanging it with the first element of the array. The lowest number will now
at the top of the list.
As a second step, the lowest number of the remaining n-1 numbers is going to
be searched and it will be exchanged with the second element of the array. The
second lowest number will be now the second in the list.
Continuing with this process, it will be searched for the lowest number among
the remaining n-2 numbers and it will be exchanged with the third element in
the array, and so on until all of the array be sorted.
It will be required a total of n-1 steps for sorting the array, but the length of
each search will be diminished at each step.
In order to find the lowest number at each step, each number x[i] in the array
will be sequentially compared to a starting number x[loc], where "loc" is an
integer variable used to "mark" one of the elements of the array.
If x[i] is lower than x[loc], both numbers are exchanged themselves, if not they
stay at their original places.
Once the above method has been applied to the complete array, the first
number will be the lowest one. Continuing with the above method, the process
is repeated n-2 times, until complete a total of n-1 steps (loc =1, 2,...,n-1).
The only question to be answered is how to exchange two numbers. Firstly, the
value of x[loc]. is reserved for future reference. After that the actual value of
x[i] is assigned to x[loc]. Finally, the "original value" of x[loc], which has been
previously reserved, is assigned to x[i]; the exchange of numbers has been
completed.
The above method can be implemented in a Pascal procedure, named
"exchange", as is shown as follows:
PROCEDURE Exchange;
(* Sorts the elements of an array *)
BEGIN
FOR loc := 1 TO n-1 DO
FOR i := loc + 1 TO n DO
IF x[i] < x [loc] THEN
BEGIN
temp := x[loc];
x[loc] := x[i];
x[i] := temp
END
END;
In the above procedure is assumed that "loc", "i" and "n" are integer variables
in the range 1 to 100. It is also assumed that "temp" is a real variable used to
temporarily storage x[loc]. Notice that the procedure uses nested for-loops.
Consider now the strategy for the general program:
1. Read the array size, n.
2. Read the n elements of the array.
3. Sort the elements of the array using the above procedure.
4. Write the sorted elements.
Here it is the complete program:
PROGRAM Sorting (input, output);
(* This program sorts a real one-dimensional array *)
VAR
n, i, loc : 1..100;
x : ARRAY [1..100] OF real;
temp : real;
(* ********************************************** *)
PROCEDURE Exchange;
(* Sorts the elements of an array *)
BEGIN
FOR loc := 1 TO n-1 DO
FOR i := loc + 1 TO n DO
IF x[i] < x[loc] THEN
BEGIN
temp := x[loc];
x[loc] := x[i];
x [i] := temp
END
END; (* Exchange *)
(* ********************************************** *)
BEGIN (* Main program *)
write ('How Many numbers? : ');
readln (n);
FOR i := 1 TO n DO
BEGIN
write ('x[',i:3, ']= ');
readln (x[i])
END;
exchange;
writeln (' sorted data: ');
FOR i := 1 To n Do
writeln (' x[',i:3,']= ', x[i]:4:1);
readln
END.
12.3 Strings
It has been probably though of an string as an array of type "char". This is true
with two exceptions:
i) Strings use index 0 to store the length byte of the string.
ii) Strings always start "char" date at index 1.
A string variable is declared in the following way
VAR
stringname : STRING[length];
or in the following way
TYPE
stringtype = STRING[length];
VAR
stringname : stringtype;
Notice that when a string variable is declared, it is usually specified the
maximum length that will be needed.
Pascal stores string data a little differently than integers or reals. Strings have
two parts:
i) The number of characters in the string.
ii) The actual characters of the string.
With the storing of integers and reals it is used an analogy of a box inside the
computer.
With the storing of strings, think of a series of adjacent boxes. The first box
stores the number of characters in the string and is called the "length byte". The
remaining boxes store the characters of the string (one character per box).
String variables can hold strings as long as 255 characters. This should be more
than ample for most applications.
Obviously the "length byte" can be computed using function "ord" in the
following way".
ord (stringname [0]);
To obtain the current length of a string it is used function "length":
length (stringname);
This current length consists only of the number of characters in the string. It
does not include the length byte.
According to the above remarks if a string variable is declared as STRING[30],
then it is told to Pascal to use 31 bytes (do not forget the length byte) to store
the string data. If the input string is composed of 5 characters, Pascal still uses
31 bytes. However, the length byte is a "char" value of 5, and the data in
STRING[6] through STRING[30] is undefined.
The following program illustrates the above remarks and how a string can be
treated as an array. The last "writeln" shows how it is usually displayed an
string.
Pascal programming lecture notes
Pascal programming lecture notes
Pascal programming lecture notes
Pascal programming lecture notes
Pascal programming lecture notes
Pascal programming lecture notes
Pascal programming lecture notes
Pascal programming lecture notes
Pascal programming lecture notes
Pascal programming lecture notes
Pascal programming lecture notes
Pascal programming lecture notes
Pascal programming lecture notes

Weitere ähnliche Inhalte

Was ist angesagt?

Intro To Programming Concepts
Intro To Programming ConceptsIntro To Programming Concepts
Intro To Programming ConceptsJussi Pohjolainen
 
Programing paradigm &amp; implementation
Programing paradigm &amp; implementationPrograming paradigm &amp; implementation
Programing paradigm &amp; implementationBilal Maqbool ツ
 
Types of Programming Errors
Types of Programming ErrorsTypes of Programming Errors
Types of Programming ErrorsNeha Sharma
 
What is token c programming
What is token c programmingWhat is token c programming
What is token c programmingRumman Ansari
 
Pascal Programming Language
Pascal Programming LanguagePascal Programming Language
Pascal Programming LanguageReham AlBlehid
 
pseudo code basics
pseudo code basicspseudo code basics
pseudo code basicsSabik T S
 
Programming Fundamental Slide No.1
Programming Fundamental Slide No.1Programming Fundamental Slide No.1
Programming Fundamental Slide No.1Arslan Hussain
 
Keywords, identifiers ,datatypes in C++
Keywords, identifiers ,datatypes in C++Keywords, identifiers ,datatypes in C++
Keywords, identifiers ,datatypes in C++Ankur Pandey
 
constants, variables and datatypes in C
constants, variables and datatypes in Cconstants, variables and datatypes in C
constants, variables and datatypes in CSahithi Naraparaju
 
Introduction to c programming
Introduction to c programmingIntroduction to c programming
Introduction to c programmingManoj Tyagi
 
History of Computer Programming Languages.pptx
History of Computer Programming Languages.pptxHistory of Computer Programming Languages.pptx
History of Computer Programming Languages.pptxAliAbbas906043
 

Was ist angesagt? (20)

Intro To Programming Concepts
Intro To Programming ConceptsIntro To Programming Concepts
Intro To Programming Concepts
 
Programing paradigm &amp; implementation
Programing paradigm &amp; implementationPrograming paradigm &amp; implementation
Programing paradigm &amp; implementation
 
Pseudocode
PseudocodePseudocode
Pseudocode
 
Types of Programming Errors
Types of Programming ErrorsTypes of Programming Errors
Types of Programming Errors
 
What is token c programming
What is token c programmingWhat is token c programming
What is token c programming
 
Pascal Programming Language
Pascal Programming LanguagePascal Programming Language
Pascal Programming Language
 
Introduction to c++ ppt
Introduction to c++ pptIntroduction to c++ ppt
Introduction to c++ ppt
 
Algorithm and flowchart
Algorithm and flowchartAlgorithm and flowchart
Algorithm and flowchart
 
pseudo code basics
pseudo code basicspseudo code basics
pseudo code basics
 
Compilers
CompilersCompilers
Compilers
 
Computer programming
Computer programmingComputer programming
Computer programming
 
Programming Fundamental Slide No.1
Programming Fundamental Slide No.1Programming Fundamental Slide No.1
Programming Fundamental Slide No.1
 
Programming
ProgrammingProgramming
Programming
 
Keywords, identifiers ,datatypes in C++
Keywords, identifiers ,datatypes in C++Keywords, identifiers ,datatypes in C++
Keywords, identifiers ,datatypes in C++
 
constants, variables and datatypes in C
constants, variables and datatypes in Cconstants, variables and datatypes in C
constants, variables and datatypes in C
 
Introduction to c programming
Introduction to c programmingIntroduction to c programming
Introduction to c programming
 
Types of system software
Types of system softwareTypes of system software
Types of system software
 
Problem solving methodology
Problem solving methodologyProblem solving methodology
Problem solving methodology
 
History of Computer Programming Languages.pptx
History of Computer Programming Languages.pptxHistory of Computer Programming Languages.pptx
History of Computer Programming Languages.pptx
 
Graphical programming
Graphical programmingGraphical programming
Graphical programming
 

Andere mochten auch

G.C.E O/L ICT Short Notes Grade-11
G.C.E O/L ICT Short Notes Grade-11G.C.E O/L ICT Short Notes Grade-11
G.C.E O/L ICT Short Notes Grade-11Mahesh Kodituwakku
 
Grade 10 ICT Short Notes in Sinhala(2015)
Grade 10 ICT Short Notes in Sinhala(2015)Grade 10 ICT Short Notes in Sinhala(2015)
Grade 10 ICT Short Notes in Sinhala(2015)Mahesh Kodituwakku
 
ICT G.C.E O/L 2016 Model Paper
ICT G.C.E O/L 2016 Model PaperICT G.C.E O/L 2016 Model Paper
ICT G.C.E O/L 2016 Model PaperMahesh Kodituwakku
 
G.C.E. O/L ICT Lessons Database sinhala
 G.C.E. O/L ICT Lessons Database sinhala G.C.E. O/L ICT Lessons Database sinhala
G.C.E. O/L ICT Lessons Database sinhalaMahesh Kodituwakku
 
පරිගණකයේ විකාශය
පරිගණකයේ විකාශයපරිගණකයේ විකාශය
පරිගණකයේ විකාශයRajith Pemabandu
 
A historical note on schwartz space and test or bump functions
A historical note on schwartz space and test or bump functionsA historical note on schwartz space and test or bump functions
A historical note on schwartz space and test or bump functionsAlejandro Domínguez Torres
 

Andere mochten auch (20)

Pascal programming language
Pascal programming languagePascal programming language
Pascal programming language
 
G.C.E O/L ICT Short Notes Grade-11
G.C.E O/L ICT Short Notes Grade-11G.C.E O/L ICT Short Notes Grade-11
G.C.E O/L ICT Short Notes Grade-11
 
Grade 10 ICT Short Notes in Sinhala(2015)
Grade 10 ICT Short Notes in Sinhala(2015)Grade 10 ICT Short Notes in Sinhala(2015)
Grade 10 ICT Short Notes in Sinhala(2015)
 
GCE O/L ICT
GCE O/L ICT GCE O/L ICT
GCE O/L ICT
 
ICT G.C.E O/L 2016 Model Paper
ICT G.C.E O/L 2016 Model PaperICT G.C.E O/L 2016 Model Paper
ICT G.C.E O/L 2016 Model Paper
 
G.C.E. O/L ICT Lessons Database sinhala
 G.C.E. O/L ICT Lessons Database sinhala G.C.E. O/L ICT Lessons Database sinhala
G.C.E. O/L ICT Lessons Database sinhala
 
ICT Lessons in Sinhala
ICT Lessons in SinhalaICT Lessons in Sinhala
ICT Lessons in Sinhala
 
පරිගණකයේ විකාශය
පරිගණකයේ විකාශයපරිගණකයේ විකාශය
පරිගණකයේ විකාශය
 
GIT Model Paper
GIT Model PaperGIT Model Paper
GIT Model Paper
 
Liderando proyectos de it
Liderando proyectos de itLiderando proyectos de it
Liderando proyectos de it
 
A historical note on schwartz space and test or bump functions
A historical note on schwartz space and test or bump functionsA historical note on schwartz space and test or bump functions
A historical note on schwartz space and test or bump functions
 
Es usted un líder de proyectos
Es usted un líder de proyectosEs usted un líder de proyectos
Es usted un líder de proyectos
 
Cambio y conocimiento en los sistemas
Cambio y conocimiento en los sistemasCambio y conocimiento en los sistemas
Cambio y conocimiento en los sistemas
 
Representaciones de Fibonacci
Representaciones de FibonacciRepresentaciones de Fibonacci
Representaciones de Fibonacci
 
Fundamentos para el desarrollo de proyectos
Fundamentos para el desarrollo de proyectosFundamentos para el desarrollo de proyectos
Fundamentos para el desarrollo de proyectos
 
Tomando el control del ruido organizacional
Tomando el control del ruido organizacionalTomando el control del ruido organizacional
Tomando el control del ruido organizacional
 
Pm in noisy environments
Pm in noisy environmentsPm in noisy environments
Pm in noisy environments
 
Education service delivery
Education service deliveryEducation service delivery
Education service delivery
 
Importancia de la teoría de operadores
Importancia de la teoría de operadoresImportancia de la teoría de operadores
Importancia de la teoría de operadores
 
El colapso de los proyectos
El colapso de los proyectosEl colapso de los proyectos
El colapso de los proyectos
 

Ähnlich wie Pascal programming lecture notes

Intro To C++ - Class 03 - An Introduction To C++ Programming, Part II
Intro To C++ - Class 03 - An Introduction To C++ Programming, Part IIIntro To C++ - Class 03 - An Introduction To C++ Programming, Part II
Intro To C++ - Class 03 - An Introduction To C++ Programming, Part IIBlue Elephant Consulting
 
Report on c and c++
Report on c and c++Report on c and c++
Report on c and c++oggyrao
 
1.1 programming fundamentals
1.1 programming fundamentals1.1 programming fundamentals
1.1 programming fundamentalsJawad Khan
 
ProgFund_Lecture_7_Intro_C_Sequence.pdf
ProgFund_Lecture_7_Intro_C_Sequence.pdfProgFund_Lecture_7_Intro_C_Sequence.pdf
ProgFund_Lecture_7_Intro_C_Sequence.pdflailoesakhan
 
Chapter 2 - Structure of C++ Program
Chapter 2 - Structure of C++ ProgramChapter 2 - Structure of C++ Program
Chapter 2 - Structure of C++ ProgramDeepak Singh
 
A Project Based Lab Report On AMUZING JOKE
A Project Based Lab Report On AMUZING JOKEA Project Based Lab Report On AMUZING JOKE
A Project Based Lab Report On AMUZING JOKEDaniel Wachtel
 
Overview of C Mrs Sowmya Jyothi
Overview of C Mrs Sowmya JyothiOverview of C Mrs Sowmya Jyothi
Overview of C Mrs Sowmya JyothiSowmya Jyothi
 
Basics Of C++.pptx
Basics Of C++.pptxBasics Of C++.pptx
Basics Of C++.pptxDineshDhuri4
 
INTRODUCCIÓN A LA PROGRAMACIÓN
INTRODUCCIÓN A LA PROGRAMACIÓNINTRODUCCIÓN A LA PROGRAMACIÓN
INTRODUCCIÓN A LA PROGRAMACIÓNBenjaminAnilema
 
Intro to c programming with all basic concept with clear explanation and example
Intro to c programming with all basic concept with clear explanation and exampleIntro to c programming with all basic concept with clear explanation and example
Intro to c programming with all basic concept with clear explanation and exampleseccoordpal
 
Intermediate code- generation
Intermediate code- generationIntermediate code- generation
Intermediate code- generationrawan_z
 
Programming For As Comp
Programming For As CompProgramming For As Comp
Programming For As CompDavid Halliday
 

Ähnlich wie Pascal programming lecture notes (20)

Input-output
Input-outputInput-output
Input-output
 
Intro To C++ - Class 3 - Sample Program
Intro To C++ - Class 3 - Sample ProgramIntro To C++ - Class 3 - Sample Program
Intro To C++ - Class 3 - Sample Program
 
Intro To C++ - Class 03 - An Introduction To C++ Programming, Part II
Intro To C++ - Class 03 - An Introduction To C++ Programming, Part IIIntro To C++ - Class 03 - An Introduction To C++ Programming, Part II
Intro To C++ - Class 03 - An Introduction To C++ Programming, Part II
 
C programming
C programmingC programming
C programming
 
Report on c and c++
Report on c and c++Report on c and c++
Report on c and c++
 
1.1 programming fundamentals
1.1 programming fundamentals1.1 programming fundamentals
1.1 programming fundamentals
 
ProgFund_Lecture_7_Intro_C_Sequence.pdf
ProgFund_Lecture_7_Intro_C_Sequence.pdfProgFund_Lecture_7_Intro_C_Sequence.pdf
ProgFund_Lecture_7_Intro_C_Sequence.pdf
 
Intro to c++
Intro to c++Intro to c++
Intro to c++
 
Chapter 2 - Structure of C++ Program
Chapter 2 - Structure of C++ ProgramChapter 2 - Structure of C++ Program
Chapter 2 - Structure of C++ Program
 
A Project Based Lab Report On AMUZING JOKE
A Project Based Lab Report On AMUZING JOKEA Project Based Lab Report On AMUZING JOKE
A Project Based Lab Report On AMUZING JOKE
 
Chap 2 c++
Chap 2 c++Chap 2 c++
Chap 2 c++
 
Overview of C Mrs Sowmya Jyothi
Overview of C Mrs Sowmya JyothiOverview of C Mrs Sowmya Jyothi
Overview of C Mrs Sowmya Jyothi
 
Qbasic Tutorial
Qbasic TutorialQbasic Tutorial
Qbasic Tutorial
 
Basics Of C++.pptx
Basics Of C++.pptxBasics Of C++.pptx
Basics Of C++.pptx
 
INTRODUCCIÓN A LA PROGRAMACIÓN
INTRODUCCIÓN A LA PROGRAMACIÓNINTRODUCCIÓN A LA PROGRAMACIÓN
INTRODUCCIÓN A LA PROGRAMACIÓN
 
Qbasic tutorial
Qbasic tutorialQbasic tutorial
Qbasic tutorial
 
C Programming Unit-1
C Programming Unit-1C Programming Unit-1
C Programming Unit-1
 
Intro to c programming with all basic concept with clear explanation and example
Intro to c programming with all basic concept with clear explanation and exampleIntro to c programming with all basic concept with clear explanation and example
Intro to c programming with all basic concept with clear explanation and example
 
Intermediate code- generation
Intermediate code- generationIntermediate code- generation
Intermediate code- generation
 
Programming For As Comp
Programming For As CompProgramming For As Comp
Programming For As Comp
 

Mehr von Alejandro Domínguez Torres

La estrategia de Wile E. Coyote para atrapar al Correcaminos
La estrategia de Wile E. Coyote para atrapar al CorrecaminosLa estrategia de Wile E. Coyote para atrapar al Correcaminos
La estrategia de Wile E. Coyote para atrapar al CorrecaminosAlejandro Domínguez Torres
 
Cómo no crear una oficina de dirección de proyectos
Cómo no crear una oficina de dirección de proyectosCómo no crear una oficina de dirección de proyectos
Cómo no crear una oficina de dirección de proyectosAlejandro Domínguez Torres
 
Teoría y tendencias actuales de la administración
Teoría y tendencias actuales de la administraciónTeoría y tendencias actuales de la administración
Teoría y tendencias actuales de la administraciónAlejandro Domínguez Torres
 
¿Todos los PMPs pueden ser directores de proyectos?
¿Todos los PMPs pueden ser directores de proyectos?¿Todos los PMPs pueden ser directores de proyectos?
¿Todos los PMPs pueden ser directores de proyectos?Alejandro Domínguez Torres
 
La profesionalización de la dirección de proyectos
La profesionalización de la dirección de proyectosLa profesionalización de la dirección de proyectos
La profesionalización de la dirección de proyectosAlejandro Domínguez Torres
 
El valor profesional y organizacional de la dirección de proyectos
El valor profesional y organizacional de la dirección de proyectosEl valor profesional y organizacional de la dirección de proyectos
El valor profesional y organizacional de la dirección de proyectosAlejandro Domínguez Torres
 
The limiting absorption principle for the elastic equations
The limiting absorption principle for the elastic equationsThe limiting absorption principle for the elastic equations
The limiting absorption principle for the elastic equationsAlejandro Domínguez Torres
 
Aplicaciones de los sistemas ecuaciones a la electricidad
Aplicaciones de los sistemas ecuaciones a la electricidadAplicaciones de los sistemas ecuaciones a la electricidad
Aplicaciones de los sistemas ecuaciones a la electricidadAlejandro Domínguez Torres
 

Mehr von Alejandro Domínguez Torres (20)

Cómo elegir un posgrado webinar
Cómo elegir un posgrado   webinarCómo elegir un posgrado   webinar
Cómo elegir un posgrado webinar
 
La estrategia de Wile E. Coyote para atrapar al Correcaminos
La estrategia de Wile E. Coyote para atrapar al CorrecaminosLa estrategia de Wile E. Coyote para atrapar al Correcaminos
La estrategia de Wile E. Coyote para atrapar al Correcaminos
 
Problemas actuales en la educación
Problemas actuales en la educaciónProblemas actuales en la educación
Problemas actuales en la educación
 
Vida Después de la Universidad
Vida Después de la UniversidadVida Después de la Universidad
Vida Después de la Universidad
 
Cómo no crear una oficina de dirección de proyectos
Cómo no crear una oficina de dirección de proyectosCómo no crear una oficina de dirección de proyectos
Cómo no crear una oficina de dirección de proyectos
 
Después de una carrera técnica
Después de una carrera técnicaDespués de una carrera técnica
Después de una carrera técnica
 
Un emprendedor nunca deja de capacitarse
Un emprendedor nunca deja de capacitarseUn emprendedor nunca deja de capacitarse
Un emprendedor nunca deja de capacitarse
 
Teoría y tendencias actuales de la administración
Teoría y tendencias actuales de la administraciónTeoría y tendencias actuales de la administración
Teoría y tendencias actuales de la administración
 
Carreras con futuro
Carreras con futuroCarreras con futuro
Carreras con futuro
 
Cómo conseguir empleo
Cómo conseguir empleoCómo conseguir empleo
Cómo conseguir empleo
 
La vida después de la universidad
La vida después de la universidadLa vida después de la universidad
La vida después de la universidad
 
¿Todos los PMPs pueden ser directores de proyectos?
¿Todos los PMPs pueden ser directores de proyectos?¿Todos los PMPs pueden ser directores de proyectos?
¿Todos los PMPs pueden ser directores de proyectos?
 
La profesionalización de la dirección de proyectos
La profesionalización de la dirección de proyectosLa profesionalización de la dirección de proyectos
La profesionalización de la dirección de proyectos
 
El valor profesional y organizacional de la dirección de proyectos
El valor profesional y organizacional de la dirección de proyectosEl valor profesional y organizacional de la dirección de proyectos
El valor profesional y organizacional de la dirección de proyectos
 
La ingeniera social y la seguridad en ti
La ingeniera social y la seguridad en tiLa ingeniera social y la seguridad en ti
La ingeniera social y la seguridad en ti
 
The limiting absorption principle for the elastic equations
The limiting absorption principle for the elastic equationsThe limiting absorption principle for the elastic equations
The limiting absorption principle for the elastic equations
 
Aplicaciones de los sistemas ecuaciones a la electricidad
Aplicaciones de los sistemas ecuaciones a la electricidadAplicaciones de los sistemas ecuaciones a la electricidad
Aplicaciones de los sistemas ecuaciones a la electricidad
 
Applications of analytic geometry
Applications of analytic geometryApplications of analytic geometry
Applications of analytic geometry
 
Plan estratégico de la calidad
Plan estratégico de la calidadPlan estratégico de la calidad
Plan estratégico de la calidad
 
Calidad en la empresa - curso
Calidad en la empresa - cursoCalidad en la empresa - curso
Calidad en la empresa - curso
 

Pascal programming lecture notes

  • 1. PASCAL LECTURE NOTES DR. ALEJANDRO DOMINGUEZ ING. EDGAR HERRADOR FUNDACION ARTURO ROSENBLUETH 1993
  • 2. INTRODUCTION Programming languages are divided in special purpose languages and general purpose languages. Each special purpose language is intended for a particular application area. Pascal is probably the best, widely available, general purpose programming language in the world at the present time, especially as a vehicle for learning the principles of good programming. Pascal was named after the 17th century French mathematician, and it is available on almost every computer - from great machines to tiny microprocessors. Pascal has three main advantages over most other languages. These advantages are: Transparency: A program is said to be transparent if it is easy to read and easy understand. Given a well-written Pascal program, it can easily be seen what its intended effect is. Efficiency: This concerns the size of programs and the speed at which they run on the computer. To be efficient, a program should be small and fast - it does not matter how long the Pascal source program is. Security: After writing a program in Pascal, the computer, and in particular the compiler, is able to spot mistakes. Because Pascal programs are transparent, the programmer tends to make fewer mistakes. So, in this context, security does not mean locking something away where no-one can get at it; it means that not much is likely to go wrong without being noticed. This course is to show how to write Pascal programs which are transparent, efficient and secure.
  • 3. CHAPTER 1 Getting Started 1.1. The form of a program A Pascal program has the form PROGRAM n (output) BEGIN { statements (Pascal instructions) }; END. The first line of the program is called the 'program heading'. The rest of the program is the 'program body'. PROGRAM, BEGIN and END are 'reserved words'. This means that they can be used only in the context they are intended. They cannot serve as names. To distinguish reserved words from names, upper case (capitals) letters are used for reserved words and (mainly) lower case letters for names. The letter "n" above is a program name invented by the programmer. A name in Pascal is called a identifier: It may contain only letters and digits and must start with a letter. Some compilers regard only the first eight characters of an identifier to be significant and ignore the rest. An identifier must be something meaningful.
  • 4. The identifier "output" within the program heading signifies that the program will produce output at the terminal. This is not a reserved word. In Pascal, successive statements are separated by semicolons. Notice that the program finishes with a full stop. 1.2 Output 1.2.1 'writeln' A line of output can be produced by a 'writeln-statement' of the following form writeln('...') where the dots represent the sequence of characters to be printed. The apostrophes are called 'string quotes' and a sequence of characters enclosed between string quotes is called a 'string'. Thus, for example, the program PROGRAM Merry1 (output); BEGIN writeln('Merry Christmas') END. will print the message Merry Christmas
  • 5. The writeln-statement may produce various outputs as it can be seen in the following examples: writeln('this''ll work won''t it')---> this'll work won't it writeln('Merry','Christmas') ---> MerryChristmas writeln('Merry', 'Christmas') ---> MerryChristmas writeln('Merry ', 'Christmas') ---> Merry Christmas One writeln-statement produces all its outputs on one line. To produce output on more than one line, more than one writeln-statement must be used. The program PROGRAM Merry2 (output); BEGIN writeln('Merry Christmas'); writeln('Happy New Year') END. will produce two lines of output Merry Christmas Happy New Year The identifier "writeln" is the name of something known as a 'procedure' and the strings supplied by the programmer are known as 'parameters'. When a writeln-statement is activated one is said to be 'calling' the procedure. It is possible to call the procedure "writeln" with no parameters and then its effect at run-time is to print nothing; it simply moves the cursor down to the start of the next line.
  • 6. The program PROGRAM Merry3 (output); BEGIN writeln('Merry Christmas'); writeln; writeln('Happy New Year') END. will produce three lines of output Merry Christmas Happy New Year Thus in the above program the effect of the parameterless writeln- statement is to produce a blank between "Merry Christmas" and "Happy New Year". 1.2.2 'write' A write-statement has the same form as a writeln-statement except that "write" replaces "writeln" and at least one parameter must be supplied. The effect at rub time is the same except that the current output line is not terminated; output from successive write-statements appears on the same line.
  • 7. A writeln-statement with three parameters "a", "b" and "c" writeln(a, b, c) is equivalent to the two statements write(a, b, c); writeln and these, in turn, are equivalent to the four statements write(a); write(b); write(c); writeln 1.3 Program layout Certain layout conventions shall be adopted in what follows and the programmers is advised to follow suit since they are a mayor contributory factor towards transparency. (a) Nothing precedes PROGRAM, BEGIN or END on a line. (b) PROGRAM, BEGIN and END are aligned but information between BEGIN and END (and, as it will be seen later, between PROGRAM and BEGIN) is idented two or three spaces. (c) A semicolon immediately follows the first of the two items it separates. (d) Two statements on the same line are separated by few spaces. (e) A statement does not extend across one a line boundary (but this constrain will be relaxed when statements get longer. Because a semicolon separates one statement from the next, no semicolon should follow a statement which precedes END. However, a semicolon at
  • 8. this point is allowed and some people find that its inclusion simplifies the task of inserting further statements at a later date. In these lecture notes, no such superfluous semicolons will appear. 1.4 Comments Pascal permits the inclusion of 'comments' within a program in order to annotate it for the benefit of the human reader. It is customary to insert a comment at the head of a program to describe the function of the program and perhaps give such information as the names of the authors and the date the program was last amended. Any sequence of characters enclosed between braces, the curly brackets { and }, is interpreted as a comment and has no effect upon the action of the program. A comment may also be set between the compound symbols (* and *). A comment may appear at any point in the program at which a space would be legal. Here is an example of a program containing a comment. PROGRAM Merry4 (output); (* Prints Christmas and New Year messages *) BEGIN writeln('Merry Christmas'); writeln; writeln('Happy New Year') END.
  • 9. CHAPTER 2 Think of a Number 2.1 Constants A number is a particular example of a constant. In Pascal numbers are of two types: 'integer' and 'real'. Examples of integer constants (with no decimal point) are: 123 -1 0 4623784502 -7897999 Examples of real constants (with a decimal point) are: 10.0 -347.8216 3.1415926 The largest integer which can be represented is available in the form of a predefined constant named "maxint". All integers must be in the range -maxint and +maxint. A typical value of "maxint" is 32767 (2^15 - 1). On a small computer, the reals range from -10^40 to +10^40 approximately and about seven significant figures might be recorded. There are two ways of representing real numbers: 'fixed point' form, as above, and 'floating point' form. The later has the form aEb number a can be an integer or fixed point real value number b must be an integer letter E is interpreted as "times 10 to the power" Some examples are:
  • 10. fixed point floating point -347.8216 -3.478216E2 0.00001 1E-5 7200000000.0 7.2E9 2.2 Expressions Numeric data can be processed using 'operators' and 'brackets'. The operators are: + represents addition - represents subtraction * represents multiplication / represents (real) division These operators are applied from left to right at any one bracket level subject to the fact that * and / take precedence over + and - Here are some examples 5 + 2 * 3 = 11 (integer) (5 + 2) * 3 = 21 (integer) 9.7 - 14.82 = -5.12 (real) 10 / 5= 2.0 (real) 7 + 8.4 / 2.1 * 2 = 15.0 (real) Arithmetic expressions may be supplied as parameters to "writeln" but, unlike strings, they are not enclosed within string quotes.
  • 11. The program PROGRAM Recta1(output); (* For a rectangle of given dimensions, this program prints its area *) BEGIN writeln('A rectangle of length 3 cm and width 2 cm'); writeln('has area ', 3 * 2, ' sq cm') END. produces the output A rectangle of length 3 cm and width 2 cm has area 6 sq cm 2.3 User-defined constants Constant declarations appear between the PROGRAM line and the BEGIN, heralded by a single occurrence of the reserved word CONST. A constant 'declaration' has the form CONST i1 = c1; i2 = c2; ... ... where i1, i2, ... are identifiers and c1, c2, ... are constants Notice that each declaration is followed by a semicolon.
  • 12. An example is the following program. PROGRAM Recta2 (output); (* For a rectangle of given dimensions, this program prints its area *) CONST length = 3; width = 2; BEGIN write('A rectangle of length ', length, ' cm'); writeln(' and width ', width, ' cm'); writeln(' has area ', length * width, ' sq cm') END. Apart from spacing and some minor modifications, this program produces the same output as the previous version. But there are some improvements: 'Transparency': The relevance of each constant, and hence each expression, is clearer. 'Modification': This program can be applied to a different rectangles more easily than the previous version - the values are changed in the constant definition. In the previous program, the entire program has to be scanned in order to change every occurrence of each constant. The improved program is not only easier to modify, it is safer - there is less chance of making a mistake when making changes.
  • 13. 2.4 Formatted output A field width can be specified for any parameter of "write" or "writeln". If the field is too wide, the output is 'right-justified' and the field 'space- filled' from the left. If the field width specified for an arithmetic value is too small, it is ignored and the minimum field width necessary is used. So if a field width of 1 is supplied, no additional spaces will be output. If the parameter of "write" or "writeln" is a string or an integer number, the syntax for a formatted output must be of the form write(parameter : fieldwidth) or writeln(parameter : filedwidth) If the parameter of "write" or "writeln" is a real number, the syntax for a formatted output must be of the form write(parameter : fieldwidth : decimalplaces) or writeln(parameter : fieldwidth : decimalplaces) Thus, the three statements writeln('*', 7:1, ' ' :6, 423 :1, 6 :5); writeln('*', 49 :8, 'Fred' :9); writeln('*', 5.6789 :5:2) produce the following output *7bbbbbb423bbbb6 *bbbbbb49bbbbbFred *b5.6
  • 14. 2.5 Variables A 'variable' is an identifier which may be associated with different values (but all of the same type) at different times during the execution of a program. Variable declarations appear between the constant declarations (if there are any) and BEGIN, heralded by the single occurrence of the reserved word VAR. Variable declarations have the form VAR a1, a2, a3, ..., an : type1; b1, b2, b3, ..., bm : type2; ... ... ... ... ... where a's and b's are identifiers and type1 and type2 are 'types' For the present types are restricted to the types "integer" and "real". These are said to be 'scalar' types and "integer" types are also known as 'ordinal' type. Integer variables are used for things which can only be whole numbers. Real variables are used for things which may be fractional numbers. Notice that a variable declaration introduces a variable but associates no value with it - its value is said to be 'undefined'.
  • 15. 2.6 Input On way of giving a value to a variable is to type a value when the program is running and make the program give this value to the variable. Then it is said that the program 'reads' the value. Supplying data at run-time has the advantage that different runs of one program utilize different data; there is no need to change the program. If a program is to read a value from the terminal, the identifier "input" must appear in the PROGRAM line along with "output", the two being separated by a comma. PROGRAM ... (input, output); In Pascal, reading can be achieved by either of two statements: "read" and "readln". 2.6.1 'read' A read-statement has the form read(v1, v2, ..., vn) where v1, v2, ..., vn are variables, possible of different types
  • 16. The program PROGRAM NexAge (input, output); (* Increments a supplied age by 1 *) VAR agenow : integer; BEGIN write('How old are you? '); readln(agenow); writeln('After your next birthday you will be ', agenow+1) END. reads a person's age and states the age next birthday. When this program is run nothing will happen until the user types an integer. The program will then respond with the appropriate output. 2.6.2 'readln' "readln" is to "read" as "writeln" is to "write". The form is the same except that no parameter need be supplied. When "readln" is supplied with no parameters readln the program stops until it is typed the return-key (enter-key). When "readln" is supplied with parameters readln(a, b, ..., z) is equivalent to read(a, b, ..., z) + skip line The program
  • 17. PROGRAM PetShop1 (input, output); (* Sums four integers typed one per line, each possibly followed by text *) VAR pet1, pet2, pet3, pet4 : integer; BEGIN writeln('Type the number in stock of each of your ', 'four species'); writeln(' - one per line'); readln(pet1); readln(pet2); readln(pet3); readln(pet4); writeln('Total number of pets in stock is ', pet1 + pet2 + pet3 + pet4 : 1) END. accumulates the total stock in a pet shop which offers four different types of pet. Each number is read from a different line and anything typed after the number is ignored. The data could be typed in the form 7 cats 4 dogs 2 birds 1 fish and only the numbers would be read.
  • 18. CHAPTER 3 Doing Arithmetic 3.1 Assignment statement An expression can be used to assign a value to a variable. A value may be assigned to a variable by an 'assignment statement'. This has the form v := e where v is a variable, e is an expression and := is the 'assignment operator' Expression e may be a type integer if variable v has type real but otherwise variable v and expression e have the same type. Assignment operator := is read as 'becomes'. When an assignment statement is obeyed the expression on the right hand side is evaluated and the resultant value assigned to the variable on the left. Any value previously associated with the variable is lost ('overwritten'). A variable retains a value assigned to it until it subsequently acquires a different value, either by reading or by direct assignment. Expression e may include variables in the same way that in can include constants. When a variable is encountered within an expression at run-time the current variable is used. Any reference to an undefined value constitutes an error. Return to program "PetShop1", that one can be modified as follows
  • 19. PROGRAM PetShop2 (input, output); (* Sums four integers typed one per line, each possibly followed by text *) VAR pet1, pet2, pet3, pet4, totpets : integer; BEGIN writeln('Type the number in stock of each of your ', 'four species'); writeln(' - one per line'); readln(pet1); readln(pet2); readln(pet3); readln(pet4); totpets := pet1 + pet2 + pet3 + pet4; writeln('Total number of pets in stock is ', totpets :1) END. More than one assignment may be made to the same variable. Also, a variable may appear on both the left hand side an the right hand side of the same assignment statement.
  • 20. Both of these points are illustrated in the following program which prints a number and its three successors together with their squares and reciprocals. PROGRAM SqrtReci (input, output); (* Prints four consecutive integers together with their squares and reciprocals *) VAR n: integer; BEGIN write('What is the starting value? '); readln(n); writeln; writeln(' 2'); writeln(' n n 1 / n'); writeln(n :4, n * n :6, 1 / n :8:3); n := n+1; writeln(n :4, n * n :6, 1 / n :8:3); n := n+1; writeln(n :4, n * n :6, 1 / n :8:3); n := n+1; writeln(n :4, n * n :6, 1 / n :8:3) END.
  • 21. 3.2 Arithmetic expressions 3.2.1 'Arithmetic operators' The two operators +, -, * and / are applicable to integer and real operands. There are two operators which are applicable only to two integer operands and each produces an integer result. DIV - integer division (gives the integer part of division). MOD- modulo reduction (gives the remainder left by integer division). DIV and MOD have the same precedence as * and /; i.e., {* / DIV MOD} are applied before {+ -}. The first operand should be positive or zero and the second should be positive. Here are some examples. 15 DIV 7 = 2 15 MOD 7 = 1 7 DIV 15 = 0 7 MOD 15 = 7 6 DIV 6 = 1 6 MOD 6 = 0
  • 22. The following program takes a 3-digit integer, introduced as a user defined constant, and prints it backwards. PROGRAM RevInt (output); (* Reverses a positive three digit integer, specified as a user-defined constant *) CONST n = 472; VAR hundreds, tens, units : integer; BEGIN hundreds := n DIV 100; tens := (n MOD 100) DIV 10; units := n MOD 10; writeln(n, ' reversed is ', units :1, tens :1, hundreds :1) END. 3.2.2 'Standard functions' There are six functions which are applicable to real and integer operands 'x' (called parameters) and each produces a real result. sin(x)sine of x. x must be in radians cos(x) cosine of x. x must be in radians exp(x) e to the power x. e = base of natural logarithms = 2.7182818284... ln(x) natural logarithm of x. x must be > 0 sqrt(x) square root of x. x must be >= 0 arctan(x) arc tangent of x. Its result is in the range from -pi to +pi radians One way of computing the value of pi to the maximum accuracy of your machine is knowing that tan(pi/4)=1, thus pi= 4 * arctan(1): PROGRAM Pi (output);
  • 23. (* Compute the value of pi to the maximum accuracy *) BEGIN write('According to the computer the value of pi is '); writeln(4 * arctan(1) :1:15) END. Pascal does not provide an operation of exponentiation; i.e., the operation of raising any positive number to any power. But this operation may be constructed by an application of functions "exp(x)" and "ln". The expression exp(b * ln(a)) gives the value of "a" raised to the power "b". There are two functions which can supply an integer or a real result, depending upon the type of parameter supplied. abs(x) absolute magnitude of x; i.e., x becomes positive sqr(x)square of x; i.e., x * x The function "sqr(x)" should always be used when x is an expression more complicated than a single constant or variable, since Pascal evaluates functions more slowly than multiplications and additions.
  • 24. As an example consider the following program PROGRAM triang(input, output); (* This program computes the length of the hypotenuse of a right-angled triangle, given the lengths of the other two sides, as well as the sine, cosine and tangent of each of the two no-right-angles. It also computes the value of the no-right-angles *) VAR h, s1, s2, a1, a2 : real; sin1, sin2, cos1, cos2, tan1, tan2 : real; BEGIN writeln; writeln('The right-angled triangle is:'); writeln; writeln(' ¦ '); writeln(' ¦a1 '); writeln('s1 ¦ h'); writeln(' ¦ '); writeln(' ¦ a2 '); writeln(' --------- '); writeln(' s2 '); writeln; write('Enter length of side s1 = '); readln(s1); write('Enter length of side s2 = '); readln(s2);
  • 25. (* Start Computations *) h := sqrt(s1 * s1 + s2 * s2); (* compute hypotenuse h *) a1 := arctan(s2 / s1); (* compute angle a1 *) sin1 := sin(a1); (* compute sine of a1 *) cos1 := cos(a1); (* compute cosine of a1 *) tan1 := sin1 / cos1; (* compute tangent of a1 *) a2 := arctan(s1 / s2); (* compute angle a2 *) sin2 := sin(a2); (* compute sine of a2 *) cos2 := cos(a2); (* compute cosine of a2 *) tan2 := sin2 / cos2; (* compute tangent of a2 *) (* Write results *) writeln; writeln('The hypotenuse is = ',h :1:4); writeln; writeln('The angle a1 is = ',a1 :1:4, ' radians'); writeln('The sine of a1 is = ',sin1 :1:4); writeln('The cosine of a1 is = ',cos1 :1:4); writeln('The tangent of a1 is = ',tan1 :1:4); writeln; writeln('The angle a2 is = ',a2 :1:4, ' radians'); writeln('The sine of a2 is = ',sin2 :1:4); writeln('The cosine of a2 is = ',cos2 :1:4); writeln('The tangent of a2 is = ',tan2 :1:4) END.
  • 26. Two functions which map a real value onto an integer are round(x) - rounds x to the nearest integer trunc(x) - truncs x to a integer result Here are some examples: round(7.4) = 7 trunc(7.4) = 7 round(-7.4) = -7 trunc(-7.4) = -7 round(7.5) = 8 trunc(7.5) = 7 round(-7.5) = -8 trunc(-7.5) = -7 round(7.6) = 8 trunc(7.6) = 7 round(-7.6) = -8 trunc(-7.6) = -7 3.2.3 'Precision of reals' Within the computer, integers are stored exactly but reals involve some inherent error. This is because only certain number of significant figures can be stored. Suppose a decimal machine capable of storing four significant figures. The expression 1/3 evaluated to four significant figures is 0.3333. The expression 2 * (1 / 3) therefore produces 0.6666. The expression 2 / 3 evaluated to four significant figures is 0.6667. So two expressions which are mathematically equivalent can produce different values.
  • 27. CHAPTER 4 Being Choosy 4.1 If-statement The if-statement exists in a full and a shortened form. The full form is IF t THEN s1 ELSE s2 where t is a test and s1 and s2 are any statements Notice that no semicolons appear within the if-statement but a semicolon will follow the if-statement (that is, after s2) if the if-statement is followed by another statement. When the statement is encountered at run-time the test t is made. If the test holds then s1 is obeyed (and s2 is not); if the test does not hold then s2 is obeyed (and s1 is not). I either case control then passes to the statement next in sequence after the if-statement. Rather than choose which of two statements to obey it is often wished to make a simpler decision - whether to obey one statement or not. An abbreviated form of the if-statement is available for this. IF t THEN s where t is a test and s is any statement If test t holds, s is obeyed; if not, s is not obeyed. In either case control passes to the statement next in sequence after the if-statement. Tests can include the relational operators
  • 28. < less than <= less than or equal to > greater than >= greater than or equal to = equal to <> not equal to and these have the lowest precedence of all the operators. The following program, which determines the smallest of three supplied integers, includes both forms of if-statements. PROGRAM minim3(input, output); (* Determines the smallest of three integers *) VAR n1, n2, n3, min : integer; BEGIN write ('Type three integers: '); readln(n1, n2, n3); IF n1 < n2 THEN min := n1 ELSE min := n2; IF n3 < min THEN min := n3; writeln('The smallest of these is = ', min :1) END. 4.2 Case-statement
  • 29. A case-statement provides a multi-way selection based on a range of values. The usual form is CASE e OF v1 : s1; v2 : s2; . . . vn ; sn END (* CASE *) where e is an expression of some ordinal type, say t, v1, v2, ..., vn are distinct constants of type t and s1, s2, ..., sn are statements The only ordinal type it has been met is "integer" so, for the present, "t" must be integer. At run-time, only one of the 'limbs' s1, s2, ..., sn will be obeyed. The 'selector' e is evaluated and, assuming it produces one of the values v1, v2, ..., vn, the statement labeled with the appropriate value is selected. The selector must evaluate to one of the supplied case labels; failure to do so constitutes an error. Use of a case-statement is appropriate when selection is governed by an ordinal expression whose values are few and known.
  • 30. The following program uses a case statement to print the 'name' of a supplied digit. PROGRAM Digname1 (input, output); (* Names a supplied digit *) VAR digit : integer; BEGIN write('Give me a digit '); readln(digit); write('This is '); CASE digit OF 0 : writeln('zero'); 1 : writeln('one'); 2 : writeln('two'); 3 : writeln('three'); 4 : writeln('four'); 5 : writeln('five'); 6 : writeln('six'); 7 : writeln('seven'); 8 : writeln('eight'); 9 : writeln('nine') END (* CASE *); END. In the above program, it has been assumed that the cases listed are the only possible ones. Now assume that the number 23 is typed. This number is not a digit and, when running the program, 23 in never encounter. Pascal standard does not indicate what should happen if a value other than those listed is encountered. For some compilers it will result in a run-time error; for others, no statement is executed.
  • 31. Some implementations of Pascal include, as a nonstandard extension, an "else" case. This is illustrated in the following program. PROGRAM Digname2 (input, output); (* Names a supplied digit *) VAR digit : integer; BEGIN write('Give me a digit '); readln(digit); write('This is '); CASE digit OF 0 : writeln('zero'); 1 : writeln('one'); 2 : writeln('two'); 3 : writeln('three'); 4 : writeln('four'); 5 : writeln('five'); 6 : writeln('six'); 7 : writeln('seven'); 8 : writeln('eight'); 9 : writeln('nine') ELSE writeln('no a digit') END (* CASE *); END.
  • 32. One case limb may be prefixed by more than one case-label. The next program illustrates this. This program converts number grades to letter grades. PROGRAM Grades (input, output); (* Convert number grades to letter grades *) VAR grade : integer; BEGIN write('Enter the numeric grade: '); readln(grade); write('The letter grade is '); CASE grade DIV 10 OF 9, 10 : writeln('A'); 8 : writeln('B'); 7 : writeln('C'); 6 : writeln('D'); 0..5 : writeln('F') ELSE writeln('no recorded') END (* CASE *) END.
  • 33. 4.3 Compound statement Only one statement may be supplied as a case limb or following THEN or ELSE but it often wished to supply more than one. Pascal provides a means of bracketing statements together so that they become one 'compound statement'. BEGIN and END are used as statement brackets. This is illustrated in the following program. PROGRAM Order (input, output); (* Order two given integer numbers being the second the greatest *) VAR first, second, temp : integer; BEGIN write('Type two integer numbers: '); readln(first, second); IF first > second THEN BEGIN temp := first; first := second; second := temp; END; writeln('In order they are: ',first, ' ', second) END.
  • 34. 4.4 Nested conditionals A case limb or the statement following THEN or ELSE may itself be conditional or contain a conditional statement. The general form of a nested if-statement is the so-called "cascading" IF- THEN-ELSE IF ... THEN ... ELSE IF ... THEN ... ELSE . . . IF ... THEN ... ELSE . . .
  • 35. This form is illustrated in the following program PROGRAM PosNeg (input, output); (* Decides if a given real number is either positive, negative or zero *) VAR n : real; BEGIN write('Enter a real number : '); readln(n); IF n > 0 THEN writeln('The number is positive') ELSE IF n < 0 THEN writeln('The number is negative') ELSE writeln('The number is zero') END. A nesting of the form IF t1 THEN IF t2 THEN s1 ELSE s2 is not recommended since it is less easy to follow. When IF immediately follows THEN it can be difficult (for the human reader) to sort out which ELSE goes with which THEN. This is particularly so when one of the if-statements has no else-part.
  • 36. For the Pascal compiler the ELSE will be associated with the second THEN. However, this may not be apparent for the human reader. This is called the "trailing problem". There are two ways to improve transparence in this context. One, often the best, is to rewrite this section of program so that the problem does not arise. Two, is to use statement brackets to explicitly associate the ELSE with its intended THEN. BEGIN and END may be used to enclose a single statement. The earlier schema can be transformed into either IF t1 THEN BEGIN IF t2 THEN s1 END ELSE s2 to associate the ELSE with the first THEN or IF t1 THEN BEGIN IF t2 THEN s1 ELSE s2 END to associate the ELSE with the second THEN.
  • 37. On the other hand, a case-statement can be nested within an if-statement: IF ... THEN CASE ... OF . . . END (* CASE *) ELSE . . .
  • 38. CHAPTER 5 Character by Character 5.1 Char type By characters it is meant the letters of the alphabet (uppercase and lowercase), the digits 0-9, and other special characters that are used for punctuation, abbreviation, and so on. A third scalar type is "char". It comprises all the characters available in the set of characters used by the computer. The most common sets are ASCII (American Standard Code for Information Interchange) and EBCDIC (Extended Binary Coded Decimal Interchange Code). ASCII set will be assumed now on. As with the real and integer types, it can be defined constant and variables of type "char". Here are some character constant definitions: CONST space = ' '; dot = '.'; zero = '0'; A character constant is a string of length 1. A variable of type "char" is declared as: VAR x : char; Variable x can take as its value any character in the set available.
  • 39. When a value is read into a character variable only one character (string of length 1) is read from the input stream. When a character is output, unless a field width greater than 1 is specified, no extra spaces will be printed; the character will occupy only one character position. This is illustrated in the next program. PROGRAM Reveword (input, output); (* Reverses any four letter word *) VAR c1, c2, c3, c4 : char; BEGIN write('Please type a four-letter word: '); readln(c1, c2, c3, c4); writeln('Reversed, this is: ', c4, c3, c2, c1) END. The ASCII set form an ordered sequence - this is called the 'lexicographic' order: Associated with each character is an 'ordinal number', its position in the lexicographical order. The first character has ordinal number 0, the second one ordinal number 1, and so on. Any data type whose values form a countable, ordered sequence is called an 'ordinal' type. That is why "integer" was described as an ordinal type (but "real" was not). Thus characters can be used as case-statement selectors: PROGRAM GiveName (input, output); (* Prints one of four names given the initial *)
  • 40. VAR initial : char; BEGIN write ('What is your initial? : '); readln(initial); write('Hi '); CASE initial OF 'B' : writeln('Brian'); 'A' : writeln('Amanda'); 'F' : writeln('Frank'); 'C' : writeln('Christine') END (* CASE *) END. Since the ASCII set is an ordered sequence, the relational operators can be applied to any to operands of (the same) ordinal type. Consequently, it can be assumed that relations such as 'A' < 'Z' 'D' > 'C' '7' >= '4' '9' < 'A' are true. Be clear in mind of the difference between the characters '0', '1', ..., '9' and the integers 0, 1, ..., 9. Characters can be assigned to character variables, but integers cannot be assigned to characters variables. On the other hand, two integers can be multiplied, two characters cannot be multiplied. 5.2 Standard functions
  • 41. Since there is an order established for the characters, each character except the first has a predecessor, and each one except the last has a successor. Predecessors and successors are delivered by two functions: pred(x) - predecessor of char variable x succ(x) - successor of char variable x For example pred('c') = 'b' succ('c') = 'd' The following program reads a character and prints five consecutive characters centred on the supplied character. PROGRAM Charact5 (input, output); (* Prints five consecutive characters centred on a supplied character *) VAR ch : char; BEGIN write('Give me a character: '); readln(ch); writeln('Five characters centred on ', ch, ' are ', pred(pred(ch)), pred(ch), ch, succ(ch), succ(succ(ch)) ) END.
  • 42. Two functions map between characters and their ordinal numbers. These ones are chr(x) - delivers a character given its ordinal number x ord(x) - delivers the ordinal number of a supplied character x Thus, the position in the alphabet of a lower case letter represented by a variable "xx" is given by ord(xx) - ord('a') + 1 and the letter at position "yy" in the alphabet (if "yy" is an integer variable with a value in the range 1 to 26 is given by chr(ord('a') + n -1) The functions "ord(x)", "succ", and "pred" can be applied to items of any ordinal type. 5.2 Text files A file composed of characters and end-of-line markers is called a 'text' file. The two identifiers "input" and "output", used in the program heading, are the names of the 'standard' text files, one to be used for reading and one for writing. In chapter 13 the whole aspect of files in detail shall be examined in detail. For the moment it will be seen how a Pascal program can use external, non-standard, text files not associated with the terminal. There are four aspects of these files: 1. All external files with which the program is to communicate must be named in the program heading.
  • 43. 2. Non-standard text files must be declared within the program as variables type "text". 3. Before a non-standard file can be used it must be initialized either for reading or for writing. A file "f" is initialized for reading by one of the following procedures (depending on the Pascal implementation) STANDARD PASCAL TURBO PASCAL reset(f) assign(f, 'filename.$$$'); reset(f) In both cases the procedure "reset" can be applied to the file several times during the execution of a program and, each time, the file concerned is initialized for reading from the beginning. A file "g" is initialized for writing by one of the following procedures (depending on the Pascal implementation) STANDARD PASCAL TURBO PASCAL rewrite(g) assign(g, 'filename.$$$'); rewrite(g) In both implementations, file "f" must already exist (because it cannot otherwise be read). The file "g" need no to exist before the program is run. If it does exist, it will be overwritten; if it does not, and empty file "g" will be automatically created when the program is about to be run. In Turbo Pascal a file must be closed after reading from or writing to it using the statement "close(f)" 4. In both implementations, to read from or to write to a non-standard file, files "f" or "g" must be supplied as the first parameter to the input/output procedure.
  • 44. For example, two characters would be read from a text file "f" by a statement of the form read(f, c1, c2) or readln(f, c1, c2) and two characters would be written to a text file "g" by a statement of the form write(f, c1, c2) or writeln(f, c1, c2) An example of the above four aspects is the following program, which is a modification of program Reveword of section 5.1. This new program reads the four-letter word from a file, say "inrever4.$$$", and produces the reversed copy in another file, say "outreve4.$$$".
  • 45. PROGRAM Reverse4 (infile, outfile); (* Reverses any four letter word *) VAR infile, outfile : text; c1, c2, c3, c4 : char; BEGIN (* Read from file inrever4.$$$ *) assign(infile, 'inrever4.$$$'); reset(infile); readln(infile, c1, c2, c3, c4); close(infile); (* write to file outreve4.$$$ *) assign(outfile, 'outreve4.$$$'); rewrite(outfile); writeln(outfile, 'Reversed word: ', c4, c3, c2, c1); close(outfile) END.
  • 46. CHAPTER 6 Round and Round Until You Are Finished 6.1 Loops Computers are often wanted to repeat some process several times. When a program obeys a group of statements several times, it is said to be 'looping'. Loops are of two types: If it is known how many times it is wished to repeat the loop the situation is said to be 'deterministic'; if not, it is 'non- deterministic'. 6.2 'For-statement' A deterministic loop is implemented by a 'for-statement'. There are two forms of this statement: incremental (forward) for-statement and decremental (backward) for-statement. The general form of an incremental for-statement is FOR v := e1 TO e2 DO s where v is a variable of some ordinal type, say t, e1 and e2 are expressions of type t and s is any statement.
  • 47. Some remarks must be made: 1. Expressions e1 and e2 are the minimum and maximum values of variable v, respectively. 2. At the moment of starting the for-statement, variable v is initialised to the value of expression e1 and its value compared with the value of expression e2. In general, at the end of each loop variable v takes successive values e1, succ(e1), succ(succ(e1)), ..., e2 and its new value is compared with the value of e2. Thus, in some sense, v is a control variable of the number of loops or repetitions. 3. Variable v is updated automatically and the programmer must make no attempt to change its value within the loop. 4. Upon termination of the loop, variable has no value at all. 5. If e2 < e1, the loop body s is not obeyed at all; otherwise the body is executed a number of times equal to ord(e2) - ord(e1) + 1 Each execution of the loop is called an 'iteration'. The general form of a decremental for-statement is FOR v := e1 DOWNTO e2 DO s where v is a variable of some ordinal type, ast t, e1 and e2 are expression of type t and s is any statement.
  • 48. It might be noted here that 'DOWNTO' is one word, not two, there is no space in it. If e1 < e2 the loop body s is not obeyed at all; otherwise the loop body is obeyed a number of times equal to ord(e1) - ord(e2) + 1 For each successive iteration of the loop body the control variable, v, takes successive values e1, pred(e1), pred(pred(e1)), ..., e2 The following program uses both forms of for-statements to print the alphabet forwards and backwards. PROGRAM Alphabet(output); (* Prints the alphabet forwards and backwards *) VAR xx : char; BEGIN FOR xx := 'a' TO 'z' DO write(xx); writeln; FOR xx := 'z' DOWNTO 'a' DO write(xx) END.
  • 49. A loop body need not refer to the control variable. The following program raises two numbers to a specified power and the control variable merely governs the number of iterations. In this program it is also shown that a loop body may comprise several statements if they are bracketed to form a compound statement. PROGRAM Numston(input, output); (* Raises two numbers x and y to a non-negative power *) VAR x, xx, y, yy : real; n, power : integer; BEGIN write('Please give me two numbers: '); readln(x, y); write('To what power would you like it raised? '); readln(n); (* Initialize auxiliary variables *) xx := 1; yy := 1; (* Start computations *) FOR power := 1 TO n DO BEGIN xx := xx * x; yy := yy * y END; writeln(x:1:4, ' raised to the power ', n:1, ' is ', xx :9:4); writeln(y:1:4, ' raised to the power ', n:1, ' is ', yy :9:4) END.
  • 50. When one loop occurs within the body of another, the loops are said to be 'nested'. This is illustrated in the following program which writes to a file the multiplication tables from 1 to a given number n. PROGRAM Multable(input, f); (* Writes to file MULTIPLI.$$$ the multiplication tables from 1 to a given number n *) CONST max = 10; VAR f : text; i, j, n : integer; BEGIN write('Input the number of the maximum multiplication table: '); readln(n); assign(f, 'MULTIPLI.$$$'); rewrite(f); writeln(f, 'MULTIPLICATION TABLES UP TO ', n:1); FOR i := 1 TO n DO BEGIN writeln(f); writeln(f, 'TABLE OF ', i :2); writeln(f); FOR j := 1 TO max DO writeln(f, i :2, ' * ', j :2, ' = ', i*j :3) END; close(f) END. 6.3 While-statement
  • 51. Pascal provides two non-deterministic loops: a while-statement and a repeat-statement. In this section is studied the while-statement. The general form of this statement is WHILE t DO s where t is a test and s is any statement The test (t) is made 'prior' to each execution of the loop body (s). If the test proves false, control leaves the while-statement and passes to the next in sequence after the while-statement. If the test holds true, the loop is obeyed and the process repeated until the test eventually proves false. If test is false upon first entry, the loop body is not entered at all. The body of a while-loop need not be executed So, here are some guidelines for using WHILE. A while-loop is appropriate when it is not known how many times it is wanted the loop body obeyed and it may be 'not at all' The loop body (s) may be composed of either one or several statements. In the last case, it must be bracketed to form a compound statement. Three steps must be performed in every program that uses a while-loop. These are
  • 52. - initialize the loop-control (implicit in test t) variable before the loop is reached - test the loop-control variable before each loop repetition - update the loop control variable in the loop body (s) If the first step is omitted, the initial test of the loop control-variable will be meaningless. If the last step is omitted, the loop control variable value cannot change and the loop will execute "forever". The above facts are illustrated in the following program which finds and prints the time required to double a given amount of money.
  • 53. PROGRAM Banker(input, output); (* Finds and prints the time required to double a given amount of money *) VAR year : integer; depos, balanc, rate, intrst, double : real; BEGIN write('Enter the deposit amount : '); readln(depos); write('Enter the interest rate as a decimal fraction: '); readln(rate); (* Initialize year, balanc, and double *) year := 0; balanc := depos; double := 2 * depos; (* Recompute balanc until the initial deposit amount is doubled *) WHILE balanc < double DO BEGIN year := year + 1; intrst := balanc * rate; balanc := balanc + intrst END; writeln('Deposit amount is doubled after ', year:1, 'years'); writeln('New balance is ', balanc:1:2) END.
  • 54. 6.4 Comparison of while-loops and for-loops It has been said that a while-loop is anon-deterministic one, however, as shown in the next example, a while-loop can also be used to implement a counting loop. Consider the following while-loop used to find the sum of the first "n" integers, and the respective for-loop WHILE-LOOP FOR-LOOP sum := 0; sum := 0; nxtint := 1; FOR nxtint := 1 TO n DO WHILE nxtint <= n DO sum := sum + nxtint; BEGIN sum := sum + nxtint; nxtint := nxtint + 1 END; The most obvious difference between the loops is that the while-loop is longer. This illustrates that the while-loop should not be used to implement a counting loop. The for-loop is easier to write and should be used when the number of loop repetitions need can be determined before loop entry. The main reason for the extra length of the while-loop involves the manner in which the loop-control variable "nxtint" is manipulated: - "nxtint" is set to a initial value of 1 (nxtint := 1) - "nxtint" is tested before each loop repetition (nxtint <= n) - "nxtint" is updated during each loop repetition (nxtint := nxtint + 1) Although these three steps are implicit in the for-loop, they must be specified explicitly when the while-loop is used.
  • 55. If the loop-control variable is not initialised properly before the while- statement is reached, the loop-repetition test will be meaningless. If the loop control variable is not updated, the loop-repetition test will always be true and the loop will not be exited (infinite loop). 6.5 Repeat-statement The second non-deterministic loop is the repeat-statement. The general form is REPEAT s1; s2; ... sn; UNTIL t where t is a test and s1, s2, ..., sn are any statements The test (t) is made 'after' each execution of the loop body (s1, s2, ..., sn). If the test holds true, the loop is terminated and control passes to the statement next in sequence after the repeat-statement. If the test proves false, control returns to the start of the loop body and the whole process is repeated until the test eventually holds true. Once the loop is under way, a while-loop and a repeat-loop are equivalent. The difference is upon the first entry. With WHILE, the test is made 'before' the first execution of the loop body; with REPEAT, the test is made 'after' the first execution.
  • 56. The body of a repeat-loop is obeyed at least once Here are guidelines for using REPEAT. A repeat-loop is appropriate when it is not known how many times it is wanted the loop body obeyed but it must be 'at least once' More than one statement can be included within the body of a repeat-loop without being bracketed between BEGIN and END. The above facts are illustrated in the following program which computes the smallest Fibonacci number greater than some specified bound. The first two terms of the Fibonacci sequence are 0 and 1. Each successive term is the sum of the previous two. The program insists that the bound be greater than 1 and it must therefore be computed 'at least one' new term. So REPEAT must be used.
  • 57. PROGRAM Minfib (input, output); (* Computes the smallest Fibonacci number which exceeds a specified bound *) VAR bound, term1, term2, term3 : integer; BEGIN write('Specify the bound: '); readln(bound); IF bound < 1 THEN writeln(' *** bound is too small ***') ELSE BEGIN term3 := 1; term2 := 0; REPEAT term1 := term2; term2 := term3; term3 := term2 + term1 UNTIL term3 > bound; writeln('Smallest Fibonacci number greater', ' than ', bound :1, ' is ', term3 :1) END END.
  • 58. CHAPTER 7 True or False? 7.1 Boolean types Boolean data types are those which can only take values "true" or 'false". These are called 'Boolean values'. This category of data includes constants, variables, functions and expression of logic type. Hence a test following IF, WHILE and UNTIL is particular case of a 'Boolean expression'. The two values ("true" and "false") applied to Boolean data types for an ordered set where "false" precedes to "true". "false" has ordinal number 0 and "true" has ordinal number 1. Consequently "false" < "true" Boolean values can be written to a text file but not read from one. 7.2 Boolean case selector A case-statement can emulate an if-statement. The test becomes a Boolean selector and the two statements become limbs prefixed by "true" and "false". CASE t OF true : s1; false : s2 END (* CASE *) is equivalent to IF t THEN s1 ELSE s2 7.3 Boolean constants
  • 59. A user-defined constant may have type Boolean. For example, if "const1" and "const2" are two constants taken values "true" and "false", respectively, then they are declared as: CONST const1 = true; const2 = false; A common use of user-defined constants is to control the selection of output statements, particularly during the development of a program. 7.4 Boolean variables A Boolean variable can take either of the two values "true" and "false" and can acquire one of these values directly VAR b1, b2 : boolean; . . . b1 := true; b2 := false; or via a Boolean expression VAR negative, posdisc, factorfound, usersaysno, dhasreachedn : boolean; . . . negative := digit < 0; posdisc := disc > 0; factorfound := n MOD d = 0; usersaysno := reply = 'n'; dhasreachedn := d = n In the following program is applied these facts. This program prints two supplied three-letter words in alphabetical order. PROGRAM Two3lett (input, output);
  • 60. (* Prints two supplied three-letter words in alphabetical order *) VAR a1, a2, a3, b1, b2, b3 : char; ab : boolean; BEGIN writeln('Type two three-letter words, one per line:'); readln(a1, a2, a3); readln(b1, b2, b3); IF a1 < b1 THEN ab := true ELSE IF a1 > b1 THEN ab := false ELSE IF a2 < b2 THEN ab := true ELSE IF a2 > b2 THEN ab := false ELSE ab := a3 <= b3; CASE ab OF true : writeln(a1, a2, a3, ' ', b1, b2, b3); false : writeln(b1, b2, b3, ' ', a1, a2, a3) END (* CASE *) END. A Boolean variable can obviously be used to record the result of a test made within a loop.
  • 61. 7.5 Boolean functions There are three standard functions which produce a Boolean result. odd(x) - it becomes "true" if x is odd and "false" otherwise. x must be integer eoln(f) - it becomes "true" if there is no more information to be read in the current line of file f and "false" otherwise. When file is "input", the parameter f may be omitted eof(f) - It becomes "true" if there is no more information to be read in file f and "false" otherwise. When file is "input", the parameter "f" may be omitted The following program copies file "FILE1.$$$" onto file "FILE2.$$$".
  • 62. PROGRAM Copyfile (f1, f2); (* Program to copy "FILE1.$$$" onto "FILE2.$$$".It says the number of character and if the number of lines is either even or odd *) VAR f1, f2 : text; ch : char; licount, chcount : integer; BEGIN writeln; writeln('COPYING "FILE1.$$$" to "FILE2.$$$" ...'); (* Initialize file f1 and file f2 *) assign(f1, 'FILE1.$$$'); assign(f2, 'FILE2.$$$'); reset(f1); rewrite(f2); (* Initialize counter of lines and counter of characters *) licount := 0; chcount := 0;
  • 63. (* Start copy *) REPEAT (* Making copy of each line *) REPEAT (* Counting characters *) chcount := chcount + 1; (* Making copy of each character *) read(f1, ch); write(f2, ch) UNTIL eoln(f1); (* Counting lines *) licount := licount + 1; UNTIL eof(f1); (* Display results *) writeln('COPY FINISHED');
  • 64. write('The number of lines is'); IF odd(licount) THEN writeln(' odd and equals ', licount:1) ELSE writeln(' even and equals ', licount:1); write('The number of characters is'); IF odd(chcount) THEN writeln(' odd and equals ', chcount:1) ELSE writeln(' even and equals', chcount:1); (* Close files *) close(f1); close(f2) END.
  • 65. 7.6 Boolean operators If a Boolean expression is preceded by the operator NOT its value is 'inverted'. If "b" has the value "true" then "NOT b" is "false"; if "b" has the value "false then "NOT b" is "true". Boolean operators can be combined using two Boolean operators AND OR If b1 and b2 are Boolean b1 AND b2 is "true" only if b1 'and' b2 are both "true" b1 OR b2 is "true" if either b1 'or' b2 is "true" (or both are "true") Each of these operators has different precedence. Their precedence 'decreases' in the order NOT { highest precedence } AND { same precedence as DIV MOD * / } OR { same precedence as + - } In order to avoid errors when programming, bracketing must be used.
  • 66. Then, if b1 and b2 are Boolean b1 OR b2 must be written as (b1) OR (b2) b1 AND b2 must be written as (b1) AND (b2) NOT b1 must be written as NOT (b1) All brackets are necessary because of the relative priorities of operators. 7.7 Set membership Pascal allows the construction of 'sets'. Square brackets, [ and ], are used as 'set constructors' and members are separated by commas. All members of a set must have the same type, and this must be an ordinal type (and, hence, not "real"). This is called the base type of the set. A set member may be represented by any expression of the base type. Here are some examples [1, 2, 3, 5, 7, 11] { set of integers } ['a', 'e', 'i', 'o', 'u'] { set of characters } [i+1, ord('A')-1] { set of integers }
  • 67. A short hand notation is available for a contiguous group of set members. The set [4, i-2, i, 6, i+1, i-1, i-4, i+3, 5, i+2] can be written [4..6, i-2..i+3, i-4] Multiple occurrences of a value are equivalent to a single occurrence of that value. The set ['C'..'H', 'W', 'E', 'F'..'K', succ('A')] is the set ['C'..'K', 'W', succ('A')] Set membership can be detected with the relational operator IN The right hand operand must be a set and the left hand operand must be an expression whose type is the same as the base type of the set. The operator yields "true" only if the value of the left hand operand is currently a member of the right hand set. For example the best way to check that an integer is in the range 1 to 9 is with a set: IF digit IN [1..9] THEN ... One final note: sets are 'implementation dependent'. Both the maximum size of a set and the range of ordinal numbers that set members may possess vary from one computer to another.
  • 68. CHAPTER 8 A Matter of Routine 8.1 Some routine definitions and concepts Procedures and functions are called routines. A routine is essentially a small piece of program with an associate name. Routines offer two benefits: 1) Transparency is improved when the purpose of a group of statements is indicated by a single. 2) Duplication is avoided when one routine is "called" several times. A procedure is a routine which causes some change. Consequently, a procedure call constitutes a statement. A function is a routine which causes no change but computes a value. Consequently, a function call constitutes an expression. Some standard procedures have already been found (write, writeln, read, readln, etc), as well as some functions (sin, cos, sqrt, odd, etc). Pascal allows to extend the number of routines available by declaring user's own. Routines must be declared between the variable declarations (if there are any) and the BEGIN of the program body.
  • 69. 8.2 Procedures A simple procedure has the basic form PROCEDURE p; BEGIN s1; s2; ...; sn END (* p *); where p is the procedure name and s1, s2, ..., sn are the statements (these constitutes the procedure body The procedure can be "called" from the main program by simply quoting its name. This gives the "procedure call statement". When a procedure is called, the statements of the procedure body are obeyed and the control returns to the statement following the call. As an example of the use of procedures consider the program to copy on file onto other (see Program Copyfile in Chapter 7). This program consists of several actions: Initialize files 1 and 2 (file 1 to be read and file 2 to be written) Initialize counter of lines and counter of characters of file 1 Start copy from file 1 to file 2 Making a copy of each line from file 1 to file 2 Making a copy of each character from file 1 to file 2 Display results Close files The complete program might have the following structure, where the actions are declared as procedures:
  • 70. PROGRAM Copyfilp (f1, f2); (* Program to copy "FILE1.$$$" onto "FILE2.$$$". It says the number of character and if the number of lines is either even or odd *) VAR f1, f2 : text; ch : char; licount, chcount : integer; (* ***************************************************** *) PROCEDURE Inifiles; (* Initialise file f1 and file f2 *) BEGIN assign(f1, 'FILE1.$$$'); assign(f2, 'FILE2.$$$'); reset(f1); rewrite(f2) END; (* initialization of files *) (* ***************************************************** *) PROCEDURE Inilicha; (* Initialize counter of lines and counter of characters *) BEGIN licount := 0; chcount := 0 END; (* initialization of counters *)
  • 71. (* ***************************************************** *) PROCEDURE Copychar; (* Copy each character from file 1 to file 2 *) BEGIN REPEAT (* Counting characters *) chcount := chcount + 1; (* Making copy of each character *) read(f1, ch); write(f2, ch) UNTIL eoln(f1) END; (* copy of characters *) (* ***************************************************** *) PROCEDURE Copyline; (* Making copy of each line from file 1 to file 2 *) BEGIN REPEAT copychar; licount := licount +1 UNTIL eof(f1) END; (* copy each line *) (* ***************************************************** *)
  • 72. PROCEDURE Copyfile; (* Start copy form file 1 to file 2 *) BEGIN copyline END; (* copy of lines *) (* ***************************************************** *) PROCEDURE Dispresu; (* Display results *) BEGIN writeln('COPY FINISHED'); write('The number of lines is'); IF odd(licount) THEN writeln(' odd and equals ', licount:1) ELSE writeln(' even and equals ', licount:1); write('The number of characters is'); IF odd(chcount) THEN writeln(' odd and equals ', chcount:1) ELSE writeln(' even and equals', chcount:1) END; (* display results *)
  • 73. (* ***************************************************** *) PROCEDURE Clofiles; (* Close files *) BEGIN close(f1); close(f2) END; (* close files *) (* ***************************************************** *) BEGIN (* Main Program *) writeln; writeln('COPYING "FILE1.$$$" onto "FILE2.$$$" ...'); Inifiles; Inilicha; Copyfile; Dispresu; Clofiles END. Notice in this program that one procedure may call another. The only restriction is that the declaration of a procedure must precede its calls. A procedure may even call itself. It is then said to display "recursion" but this is beyond the scope of the present lecture notes.
  • 74. 8.3 Localized information It have been seen that a program can contain declarations specifying entities which may be used by procedures which are declared within the program and by statements of the program body. The same applies to procedures. A procedure declaration may contain its own declarations. Any entity declared within a procedure may be used by any procedure declared within the procedure and by statements of the procedure body. Declarations within a procedure appear between the PROCEDURE line and the BEGIN of the procedure body and are subject to the same rules of order as in the main program. An entity declared within a procedure is said to be "local" to the procedure. An entity declared in the main program is said to be "global". Storage space for local variables is allocated at run-time when a procedure is entered and released when the procedure is exited. So, even if two variables in different procedure have the same name, they will refer to different storage locations at run-time. It is good practice to declare variables as locally as possible. This reduces the possibility of their corruption in other part of the program. As an example of the above remarks consider the following program.
  • 75. PROGRAM Locvar(input, output); (* Program to shows the use of local and global variables *) CONST k = 10; (* this is a global constant *) VAR ch : char; (* this is a global variable *) (* ***************************************************** *) PROCEDURE Writchar; CONST m = 5; (* this a local constant *) VAR i, km : integer; (* these are local variables *) BEGIN km := k - m; writeln('The character ', ch,' repeated ', k-m,' times is:'); FOR i := 1 TO km DO writeln(ch) END; (* ***************************************************** *) BEGIN (* MAIN PROGRAM *) writeln; write('Type any character: '); readln(ch); writchar; readln END. 8.4 Functions
  • 76. The fundamental difference between a function and a procedure is that a function call constitutes an "expression" because a function "delivers" a "result" whereas a procedure call constitutes a "statement" and no value is associated with the call. A function is a suitable form for a routine when one is interested in only one value computed by the routine and the routine produces no "side effects". A routine is said to cause a side effect if it produces any non-local change. A function with side effects is undesirable because functions are used in expressions and a program con be hard to follow if evaluation of a expression causes no-local changes. In Pascal, a function may deliver a result of any ordinal type (boolean, char, integer), of type real, on of any other type defined by the user (these are defined in future chapters). A function declaration differs from a procedure declaration in three respects: 1. -FUNCTION replaces PROCEDURE. 2. The type of the result delivered by the function is quoted (preceded by a colon) before the closing semicolon of the function heading. 3. Within the function body, there must be at least one assignment statement with the function identifier on the left hand side. As an example consider the following program for raising a number x to an integer power n. PROGRAM Raisxton (input, output); (* Raises a number a to en integer power n *)
  • 77. VAR x : real; n : integer; (* ********************************************* *) FUNCTION xtothen : real; VAR xsquared, p : real; power : integer; BEGIN If n = 0 THEN xtothen = 1 ELSE BEGIN xsquared := sqr (x) IF odd (n) THEN p := x ELSE p := 1; FOR power := 1 TO n DIV 2 DO p := p * xsquared; xtothen := p END END (* to then n *) ; (* ********************************************* *) BEGIN (* main program *) write('Please give me a number: '); readln(x); write('To what power would you like it raised: '); readln(n); writeln(x, ' raised to the power ', n :1, ' is ', xtothen);
  • 78. readln END. In order to give more examples illustrating the use of functions, consider the following two programs PROGRAM Insuranc (input, output) (* Categorizes an age into one of five groups *) VAR age : integer; (* **************************************************** *) FUNCTION groupforage : char; BEGIN CASE age DIV 5 OF 3: groupforage := 'A'; 4, 5: groupforage := 'B'; 6..9: groupforage := 'C'; 10..12: groupforage := 'D' ELSE groupforage := 'F END; (* case *) END; (* group for age *) (* **************************************************** *) BEGIN (* main program *) write('Supply an age: ') readln(age); writeln('Insurance group is: ', groupforage); readln END.
  • 79. PROGRAM Word3fns (input, output); (* Prints two supplied three-Letter words in alphabetical order *) VAR a1, a2, a3, b1, b2, b3 : char; (* ************************************************** *) FUNCTION abinorder : boolean; BEGIN IF a1 < b1 THEN abinorder := true ELSE IF a1 > b1 THEN abinorder := false ELSE IF a2 < b2 THEN abinorder := true ELSE IF a2 > b2 THEN abinorder := false ELSE abinorder := a3 <= b3 END; (* a b in order *) (* ************************************************** *) BEGIN (* main program *) writeln('Type two three-Letter words, one per line:'); readln(a1, a2, a3); readln (b1, b2, b3); CASE abinorder OF True : writeln (a1, a2, a3, ' ', b1, b2, b3); false: writeln (b1, b2, b3, ' ' , a1, a2, a3) END; (* CASE *) readln END.
  • 80. CHAPTER 9 Routine Information 9.1 Transference of parameters A program may transfer information to a procedure or obtain it from it. Assume, for the moment, that a value is going to be passed to a procedure. As an example, consider the following program having a procedure inside it exhibiting the result in a Boolean expression, as for example "yes" or "not" instead "true" or "false". Notice in this program that the Boolean value "booleanvalue" is a formal parameter used as a variable into the procedure. PROGRAM Eor (input, output); (*Simulates the "exclusive or" operation *) VAR a, b, eo : boolean; inta, intb : integer; (* ********************************************** *) PROCEDURE Yesno (booleanvalue : boolean ); (* Procedure to exhibit a boolean value *) BEGIN CASE booleanvalue OF true : write ('YES'); false: write ('NOT') END (* CASE *) END; (* Yesno *) (* ********************************************** *)
  • 81. BEGIN (* Main program *) REPEAT write ('Enter two integer values, 0 is no: '); readln (inta, intb); a := true; IF inta = 0 THEN a := false; b := true; IF intb = 0 THEN b := false; (* Eco of the input values *) write ('You input a '); yesno (a); write (' and a '); yesno (b); writeln; (* Process and prints out an eor b *) eo := (a AND NOT b) OR (b AND NOT a ); write ('The exclusive or of these ones is: '); yesno (eo); writeln UNTIL false; readln END.
  • 82. In general, a list of parameters gives the local names of the parameters as well as their types. These are called "formal parameters" of the procedure: PROCEDURE Byexample (i,j: integer; maybe: boolean; b,c,g: real)., Notice that the formal parameters are grouped by types. When a procedure is used, the correct number of parameters must be given as well as their corresponding types. 9.2 Value and variable parameters In the example given in the preceding section, a value was transferred to a procedure. But it is also frequent to transfer a value in the inverse way. Pascal distinguishes two types of parameters: value parameters: transfer values to a procedure Variable parameters: transfer values from a procedure Consider the following program:
  • 83. PROGRAM Cubevalu (input, output); (* Shows a value parameter *) VAR test : integer; (* ********************************************** *) PROCEDURE Cube (number : integer); (* computers the cube of a given number *) BEGIN number := number * number * number; writeln ('The cube of the number is: ', number) END; (* Cube *) (* ********************************************** *) BEGIN (* Main program *) writeln; write ('Enter an integer value: '); readln (test); writeln ('The test value is: ', test); cube (test); writeln ('Now the value of test is: ', test); readln END. The above program calls a procedure having a value parameter. The cube of 3, which is 27, is given when the program is run with 3 is given as input, but when the procedure has finished the value of "test" is still 3. Therefore, if a procedure modifies a value parameter then only its own temporary copy is modified.
  • 84. The above program has modified its own local copy, called "number", but "test" has not been modified. Consider now the following modification of the above program: PROGRAM Cubevari (input, output); (* Shows a variable parameter *) VAR test : integer; (* ********************************************** *) PROCEDURE Cube (VAR number : integer); (* Computers the cube of a given number *) BEGIN number := number * number * number; writeln ('The cube of the numbers is: ', number); END; (* ********************************************** *) BEGIN (* Main program *) write ('Enter an integer value: '); readln (test); writeln ('The test value is: ',test); cube (test); writeln ('Now the test value is: ',test); readln END. The reserved word "VAR" in the list of parameters specifies that "number" is a variable parameter.
  • 85. When the procedure modifies "number", the variable "test" is also modified. This is an important difference. A mixed group of value and variable parameters con be represented as follows. PROCEDURE ZAMP (VAR a,b: integer., x: real., VAR booby: boolean) Here x is a real value parameter. The other ones are variable parameters. For the case of functions, these may take parameters, they are always value parameters. As an example consider the following two programs using functions, which in turn use value parameters.
  • 86. PROGRAM Powers (input, output); (* Given x, y, m and n, the program forms x^m, y^n, (x^n)^m, (y^m)^n *) VAR x, y : real; m, n : integer; (* ********************************************* *) FUNCTION powered (x : real; n : integer) : real; VAR i : integer; p, xsquared : real; BEGIN IF n = 1 THEN powered := x ELSE BEGIN xsquared := sqr (x); IF odd (n) THEN p := x * xsquared ELSE p := xsquared; FOR i := 2 TO n DIV 2 DO p := p * xsquared; powered := p END END; (* powered *)
  • 87. (* ********************************************* *) BEGIN (* program body *) writeln('Give me two real numbers and two positive integers: '); readln(x, y, m, n); writeln(x:1:2, ' raised to the power ', m:2, ' = ', powered (x,m):1:2); writeln(y:1:2, ' raised to the power ', n:2, ' = ', powered (y,n):1:2); writeln(x:1:2, ' raised to the power ', n:2,' all raised to the power ', m :2, ' = ', raised powered (x,n), m):1:2); writeln (y:1:2, ' raised to the power ', m :2, ' all raised to the power ', n :2, ' = ', powered (powered (y,m), n):1:2); readln END.
  • 88. 9.3 Forward references It was stated at the end of section 8.2 that the declaration of a procedure must precede its calls. Pascal provides a relaxation of this rule: A "routine heading" must be declared before the routine is called but its "body" may be declared later (but in the same block of procedures). The declaration of the heading takes the form of a "forward reference". The routine heading is presented but its body is replaced by forward; When its body is declared later, it is preceded by an abbreviated heading. Only the routine identified appears following either PROCEDURE or FUNCTION. No mention is made of any parameters, nor in the case of a function, nor the type of the function. In order to illustrate the above remarks, suppose procedures A and B are given as shown next: PROCEDURE A (a,b: integer); BEGIN (* A *) END; (* A *) PROCEDURE B (x,y : real); BEGIN (* B *) A END; (* B* ) Since A is defined first, it can be called from B., however, B may not be called from A. According to the remarks given in order to make B callable from A, two changes must be made in the procedures as written: I) The heading line of procedure B, with the reserved word "forward" and a semicolon appended, is written before the definition of procedure A.
  • 89. II) The other change is in the actual heading line that accompanies procedure B; it is simple written PROCEDURE B; With no indication of the parameters. No other change is made in procedure B. Therefore the above procedure must be written as follows: PROCEDURE B (x,y: real); forward; PROCEDURE A (a,b: integer); BEGIN (* A *) END; (* A *) PROCEDURE B; BEGIN (* B *) END; (* B *)
  • 90. CHAPTER 10 Give it a Name 10.1 Introduction: types resumed In the preceding chapters it has been studied "real"; "integer", "boolean" and "char" types. The types "real", "integer" and "char" can be written to and read from a text file. Boolean types can be written to a text file but not read from one. "Integer", "boolean" and "char" types form an ordered set. This means that they can be used for selection in a case-statement or as an index in a for-loop. For any ordered type the following functions are well defined: succ (x) successor of variable x pred (x) predecessor of variable x For example: succ (3) = 4; pred ('q') = 'p' succ (false) = true; succ (true) gives an error Pascal allows to define user-defined types. In subsequent chapters it shall be seen how data can be grouped in different ways; in this chapter it shall be learnt how to define new types to represent scalars (single items).
  • 91. There are two classes of user-defined scalar types: "subrange" types and "symbolic" types. Both play a mayor role in improving the compile-time security of a program, both contribute to program efficiency and symbolic types in particular make significant contribution to a program transparency. A series of type definitions may appear between the constant declarations (if there are any) and the variable declarations (if there are any), heralded by the reserved word TYPE. Thus a "type definition" has the form. TYPE i = t; where i is an identifier and t is a type. Thus the order of declarations within any program is. Constants, Types, Variables, Procedures and functions. 10.2 Subrange types A variable of ordinal type, boolean, char, integer and symbolic (this will be studied in the next section) can be restricted to a subrange. The variable is then said to have a subrange type but inherits all the properties of its "host" type. Any attempt to give a subrange variable a value outside its permitted range constitutes an error. Notice that subranges or type "real" are not allowed. A subrange type is denoted by the upper and lower bounds separated by two dots. These bounds must be constants and the ordinal number of the lower bound must not exceed the ordinal number of the appear bound. Here are some subrange types. 1.. maxint 'A'..'Z'
  • 92. -1..17 Subrange types may be defined in terms of user defined constants (see examples below). Subrange types allow the user to check the sensible use of variables. From the "problem domain" the user decides what range of values should be sensible for each variable and specify this range in the declaration of the variable. Any attempt to assign a value outside the expected range will be prevented. Using subranges the user helps the computer to detect his or her mistakes. "Minimal subranging" should always be the aim. As examples, consider the subranges that should have been used in some previous examples. I) An age cannot be negative and is unlikely to exceed, say, 120: CONST maxage = 120; VAR agenow: 0..maxage;
  • 93. II) For any practical box, the length of each side must exceed 0: VAR length, width, depth: 1..maxint; III) In the program which asks for initials A,B,C, or F the minimal subrange is A to F: VAR initial: 'A'..'F' IV) If a program ask for a digit it is more convenient the following implementation: TYPE digits = 0..9; VAR digit : digits PROCEDURE Name (d: digits); V) Within a function which raises a real number to a positive power "n", the parameter "n" cannot be negative and so should be constrained to the natural numbers: TYPE naturals = 0..maxint; VAR m,n: naturals; FUNCTION Powered (x: real; n: naturals): real; On the other hand, subrange types provide a valuable protection against programming errors and can also be used to detect data entry errors.
  • 94. Obviously programs which "crash" when given bad input are not to be encouraged so, for input data validation, it is often better to use range types to read values and then assign these values to subranges variables only when it is known that the values are in range. For example to real a digit, it could be used two variables: VAR d: 0..9; dtyped: integer; And then read values until one is in range: REPEAT write ('please type a digit ' ); readln (dtyped) UNTIL dtyped IN [0..9]; d: = dtyped Of course, even this is not completely safe because an execution error will result if anything other than an integer is typed. 10.3 Symbolic types A symbolic type (or "enumerated" type as it is often called) is an ordered type. This type is user-defined according to the results or values expected. A symbolic type is denoted by a bracketed list of user-defined names. For example: TYPE rainbow = (red, orange, yellow, green, blue, violet); Where the type rainbow has six given values. In this example: ord (red) = 0 ord (orange) = succ (red) = 1
  • 95. Variables of type "rainbow" can be created: VAR pallet: rainbow; A symbolic type can be used as a limb in a case-selector, or as index in a for- loop. In the above example, elements of the type "rainbow" can be assigned to variables of the same type or compared among them, they also can be transferred as parameters in procedures or functions. Unfortunately, as was said before, symbolic type cannot be written to or read from files. Thus the value "red" is not the chain of characters "red", it is simply "red". However, it can be written ord (red) which is 0, and can be printed out chains for the values of type "rainbow" making an appropriate procedure. The above remark is illustrated in the following example. In this example is presented the use of a symbolic type which represents the months of the year. The programs asks for input a month number and outputs the month name. There are several ways for implementing the program, but the example illustrates a problem when using symbolic types. For the "char" type, the function chr (integer value) is opposite to function ord (character value) As it was said, function "ord" can be used for symbolic types, however there is not opposite to it in symbolic types. This program shows how to construct the opposite to "ord" for symbolic types: unord (integer) must be the opposite to ord (month).
  • 96. PROGRAM Months (output); (* Shows the conversion of elements of symbolic type: an integer is transformed to a month and the month is displayed *) TYPE month = (jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec); numonth = 1..12; VAR testmonth : month; (* ********************************************** *) PROCEDURE Givemonth (Thismonth : month); (* Displays the full month name *) BEGIN writeln; write ('This month is '); CASE thismonth OF Jan : writeln (' January '); Feb : writeln (' February '); Mar : writeln (' March '); Apr : writeln (' April '); May : writeln (' May '); Jun : writeln (' June ' ); Jul : writeln (' July '); Aug : writeln (' August '); Sep : writeln (' September '); Oct : writeln (' October '); Nov : writeln (' November '); Dec : writeln (' December '); ELSE writeln('not a month') END; (* CASE *) writeln END; (* ********************************************** *)
  • 97. FUNCTION Ordmonth (imonth : numonth): month; (* Converts an ordered integer to a month type *) VAR domonth : month; index : numonth; BEGIN domonth := jan; FOR index := 2 To imonth DO domonth := succ(domonth); ordmonth := domonth END; (* ********************************************** *) PROCEDURE Takemonth (VAR Thismonth : month); VAR imonth : numonth; BEGIN writeln; write ('Enter the number 1..12 of a month: '); readln (imonth); Thismonth := ordmonth (imonth) END; (* ********************************************** *) BEGIN (* Main program *) REPEAT Takemonth (testmonth); givemonth (testmonth); UNTIL false END. Subranges of symbolic types can be defined, for example with the type "month":
  • 98. TYPE month = (jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec); Subranges are created inside the "type" declaration itself, or in the "type" declaration of a contained block. halfore: jan .. jun; halfore: jul .. dic:
  • 99. CHAPTER 11 File it 11.1 Review of text files As a data structure, a "file" is an ordered collection of related data items, usually stored in external memory, for input to or output by a program; that is information can be read from the file and/or written to the file. The files used in Pascal programs up to this point have been "text files", whose components are characters and these characters are organized into lines. The predefined file type "text" is a standard type identifier used to declare text files. The standard system files "input" and "output" associated with the standard input (keyboard) and output (screen) devices are examples of text files, and in Chapter 5. user-defined text files were described. The predefined procedures "readln", "writeln", and "eoln" may be used only with text files. Pascal also supports nontext files, whose components may be of any type, simple or structured, except that they may not be of file type. Although attention in this section is restricted to text files, much of the discussion also applies to the other types of files considered in subsequent sections. The principal rules governing the use of text files in Pascal programs as discussed in Chapter 5 may be summarized as follows: 1. Program heading. It is good practice to include the names of all files used in a program (including the standard text files input and output) in the file list of the program heading. 2. Declaration. Each user-defined file must be declared as a file variable in the declaration part of the program. For text files, the predefined type identifier "text" can be used to specify the types of file variables.
  • 100. 3. Associating file variables with actual files: In Pascal, before a file can be used for input or output in a program, it must be associated with a disk file by calling the predefined procedure "assign" in a statement of the form. assign (file-variable, file-name); 4. Opening files for input. Each file from which data is read must first be opened for input with the predefined procedure "reset" in a statement of the form. reset (file-variable); Each such procedure call results the data pointer to the beginning of the specified file. (The standard system file "input" need not be opened for input.) 5. Each file to which data values are to be written must first be opened for output. For text files, this can be done by using the predefined procedure "rewrite" in a statement of the form. rewrite (file-variable); 6. File input: Information can be read from a text file by using the predefined procedures read and readln in the forms read (file-variable, input-list) readln (file-variable, input-list) If file-variable is omitted, values are read from the standard system file "input". 7. File output: Output can be directed to a text file by using the predefined procedures write and writeln in the forms. write (file-variable, output-list) writeln (file-variable, output-list)
  • 101. If file-variable is omitted, values are written to the standard system file "output". 8. Closing files: In Pascal, after output to a file is completed, the file should be closed by calling the predefined procedure "close" with a statement of the form. close (file-variable) Failure to do so may result in the loss of data values because they may not be transferred from the output buffer to the file. 9. Copying files: The contents of one file cannot be copied to another file by using an assignment statement of the form "file- variable-1:= file- variable-2". Rather the components must be copied one at a time. 10. Files as parameters: Formal parameters that represent files must be variable parameters. This is a consequence of Rule 9, since value parameters require copying the values of the corresponding actual parameters.
  • 102. 11.2 Nontext files While text files are frequently used in programming applications, "nontext file" are sometimes more convenient. Data written to a nontext file are transcribed, bit by bit, in exactly the same form that they have within the computer. This has several advantages over text files. The first advantage is speed. Because there is no need to make conversions from one form to another, the reading and writing are much faster. A second advantage is a wider range of types that may be written to a file or read from it. Only characters, integers, and real numbers may be read from a text file; it can be printed only these three types and boolean variables. However, anything that can be represented within the computer can be written to or read from a nontext file. Nontext files have some disadvantages, too. The cannot be printed because they are not in a printable (i.e., character) form. Similarly, they cannot be created by an editor as a text file is. There are also certain restrictions on the reading and writing that will be considered later in this section. The above disadvantages suggest the uses for nontext files. It might no want to have the output printed or displayed on the screen when the output is simply used as the input for another (or the same) program: As already seen in Chapter 2 the output of the compiler is the input for the loader. Such output is not given in a readable (that is, readable by humans) form.
  • 103. Now let consider their declaration and use. In order to declare such a file, it is used VAR filename: file of type; or alternatively, TYPE typename = file of type; VAR filename: typename; The "type" here can be almost any type: the simple types, arrays (chapters 12 and 13), or record (chapter 14) types. The only restriction is that it may not be a file type or a record type with a file type component. For example, the declarations TYPE file1 = file of integer; file2 = file of char; file3 = file of boolean; VAR f1 : file1; f2 : file2; f3 : file3; are valid definitions of files.
  • 104. It can be written to these files and read from them in much the same way as with text files. Nevertheless, there are some differences, centering around the fact that nontext files are not organized into lines as text files are. Thus, the procedures readln and writeln and the function eoln cannot be used with nontext files. The remaining functions and procedures relating to input and output-reset, rewrite, read, write, and eof-are used in much the same way as they were with text files. While the types "text" and "file of char" might appear to be equivalent, there are significant differences. The declaration VAR FileA : file of char; does not declare FileA to be a text file; it is imply a nontext file containing only characters. It is nor organized into lines: so we cannot use readln, writeln, on eoln. Furthermore, a write statement will not convert numeric or boolean values into strings of characters; nor will a read statement convert a string of numeric character into an integer or real value. If it is given the command READ (FileA, x) or write (FileA, x) With x declared to be anything other than a character type, it would result in an error. as an example of the use of nontext files, consider the following program:
  • 105. PROGRAM filesrw (data, output); (* This program creates a file of reals and writes data to it and read data from it *) VAR data: FILE OF real; value, square1, square2, root1, root2 : real; count : integer; BEGIN assign(data, 'data.$$$'); (* write data to file *) rewrite(data); FOR count := 1 TO 10 DO BEGIN value := count; square1 := sqr(value); root1 := sqrt(value); write( data, value, square1, root1) END; (* read data from file and display them to VDU *) reset(data); WHILE NOT eof(data) DO BEGIN read(data, value, square2, root2); writeln(value :6:2, square2 :8:2, root2 :6:2) END; readln END.
  • 106. CHAPTER 12 Line up 12.1 One-dimensional arrays So far, real and integer variables have been used for representing just one value reach one. However there are a lot of situations for which a program must have a list of variables of the same type represented by one only identifier. In a mathematical presentation using many variables, subscripted variables are often used; for example, x1, x2, x3,..., x [100]. Since anything cannot be written above or below the line in programming languages, Pascal uses a somewhat different notation. In Pascal, the notation is x [1], x[2], x[3],..., x[100] This is called an "array". More specifically, a "one-dimensional array" is finite sequence of variables all of the same type and all identified by the same name. One variable of an array is distinguished from another by its "subscript" or "index", which is the value of an expression given within brackets and following the array identifier. In general, a subscripted (or indexed) variable has the form identifier [expression]
  • 107. The identifier is subject to the normal restrictions of identifiers; in particular, there may be no space within it. Nevertheless, there may be one or more spaces between the identifier and the left bracket, between the left bracket and the expression, or between the expression and the right bracket. The variables used above may be declared by (if they are of integer type) VAR x: ARRAY [1..100] OF integer An alternative way of declaring the above array is by a named type-(that is, by first declaring a type, which is then used to declare the variable.). Thus, it might have. TYPE arraytype = ARRAY [1..100] OF integer; VAR x: arraytype; "Type declarations" must precede variable declarations and follow constant declarations. Pascal requires named, rather than anonymous, types when passing arrays as parameters. A subscripted variable refers to a single storage location in the array and, therefore, is used in much the same way as a simple variable. For example;
  • 108. x [1] := 5; list[7] := x[1] + y[7]; temp := list[7] read (array [4]) While arrays allow us to define hundreds or thousands of variables with a single declaration, their greatest advantage lies in the evaluation of the subscript. It is not necessary to have a constant within the declared subscript range. Whatever expression is within the brackets is evaluated, the result is the subscript. As example, suppose that a[1] = 5, a[2] = 1, a[3] = 3, a[4] = 2, a[5] = 0, b[0] = 4, b[1] = 2, b[2] = 3, b[3] = 1, i = 3, j = 2 Then a[1] = a[3] = 3, b[j-1] = b[2-1] = b[1] = 2, a[i+j] = a[3+2] = a[5] = 2, a[i-j+1] = a[3-2+1] = a[2] = -1, a[b[1]] = a[b[3]] = a[1] = 5, b[a[j]] = b[a[2]] = b[-1] is not defined a[b[a[j]+1]] = a[b[a[2]+1]] = a[b[0]] = a[4] = 2 It is this evaluation of the subscript that makes arrays so useful. With the added facility of arrays the problem of reading a list of numbers and writing it in
  • 109. reverse order is quite simply. This is show for a list of exactly 10 numbers in the following program. PROGRAM Readreve (input, output); (* Reads a list of 10 integers and prints them in reverse order *) TYPE numarraytype = ARRAY [1..10] OF integer; VAR num : numarraytype; index : integer; BEGIN writeln ('Give a list of 10 integers: '); FOR index :=1 TO 10 DO read (num[index]); (* write the number in reverse order *) writeln ('The reversed list is: '); FOR index :=10 DOWNTO 1 DO writeln (num[index]); readln END.
  • 110. Arrays can sometimes be accessed in their entirety, rather than one component at a time, in assignment statements or parameter passing. For example, if "a" and "b" are declared identically, say TYPE realarray = ARRAY [1..25] OF real; VAR a,b: realarray; Then a: = b is a valid assignment. Similarly, if the following declarations are give TYPE arraytype = ARRAY[1..25] OF real; VAR a,b : arraytype; and the procedure P parameter VAR c: arraytype; Then the procedure P may be called by P (a) or P(b). When passing an entire array, both the formal parameter and the actual parameter must be declared using the same "named" type. As an example, consider the following program PROGRAM Findmax (input, output);
  • 111. (* Shows the passing of arrays as a parameter*) TYPE demoray = ARRAY [1..4] OF integer; VAR one, two : demoray; max, index : integer; (* ********************************************** *) PROCEDURE Takearray (VAR inarray : demoray); (* An array is input *) VAR i : integer; BEGIN writeln ('Input 4 values for an array: '); FOR i :=1 TO 4 DO read (inarray [i]); writeln END;
  • 112. (* ********************************************** *) PROCEDURE Obtmax (sweeparray : demoray; VAR value, position : integer); (* Sweeps sweeparray in order to find its maximum value as well as its position *) VAR i:integer; BEGIN value := sweeparray[1]; position := 1; FOR i := 2 TO 4 DO IF Sweeparray[i] > value THEN BEGIN value := Sweeparray[i]; position := i END; END; (* ********************************************** *) BEGIN (* Main program *) writeln ('Find the maximum value of two arrays'); takearray (one); takearray (two); obtmax (one, max, index); writeln ('The maximum of the first array is: ',max, ' at the index ', index); obtmax (two, max, index); writeln ('The maximum of the second array is: ', max, ' at the index ', index); readln END.
  • 113. As it can be seen in the above program am array is passed as a variable parameter. Procedure Takearray uses an array as a variable parameter since it must return the array with its new values. Procedure obtmax uses a value parameter; but it was not necessary. However, it is better to use a variable parameter when using arrays. If a value parameter is used with arrays, the computer must waste time and space to create the copies when a procedure is called. Therefore Always pass arrays as variable parameters On the other hand, Pascal does not permit the following procedure or function heading: PROCEDURE Findmax (VAR arrent: ARRAY [1..10] OF integer, big, where, : integer); 12.2. Sorting Consider now the problem of sorting a list of n numbers according to a sequence of increasing values. The program is going to be written in such a way it does not use unnecessary memory; therefore it will contain a unique array (one-dimensional, real and having x as name) where one element is going to be reordered each time. The method begins searching for in the array the lowest number and exchanging it with the first element of the array. The lowest number will now at the top of the list. As a second step, the lowest number of the remaining n-1 numbers is going to be searched and it will be exchanged with the second element of the array. The second lowest number will be now the second in the list. Continuing with this process, it will be searched for the lowest number among the remaining n-2 numbers and it will be exchanged with the third element in the array, and so on until all of the array be sorted.
  • 114. It will be required a total of n-1 steps for sorting the array, but the length of each search will be diminished at each step. In order to find the lowest number at each step, each number x[i] in the array will be sequentially compared to a starting number x[loc], where "loc" is an integer variable used to "mark" one of the elements of the array. If x[i] is lower than x[loc], both numbers are exchanged themselves, if not they stay at their original places. Once the above method has been applied to the complete array, the first number will be the lowest one. Continuing with the above method, the process is repeated n-2 times, until complete a total of n-1 steps (loc =1, 2,...,n-1). The only question to be answered is how to exchange two numbers. Firstly, the value of x[loc]. is reserved for future reference. After that the actual value of x[i] is assigned to x[loc]. Finally, the "original value" of x[loc], which has been previously reserved, is assigned to x[i]; the exchange of numbers has been completed. The above method can be implemented in a Pascal procedure, named "exchange", as is shown as follows:
  • 115. PROCEDURE Exchange; (* Sorts the elements of an array *) BEGIN FOR loc := 1 TO n-1 DO FOR i := loc + 1 TO n DO IF x[i] < x [loc] THEN BEGIN temp := x[loc]; x[loc] := x[i]; x[i] := temp END END; In the above procedure is assumed that "loc", "i" and "n" are integer variables in the range 1 to 100. It is also assumed that "temp" is a real variable used to temporarily storage x[loc]. Notice that the procedure uses nested for-loops. Consider now the strategy for the general program: 1. Read the array size, n. 2. Read the n elements of the array. 3. Sort the elements of the array using the above procedure. 4. Write the sorted elements. Here it is the complete program:
  • 116. PROGRAM Sorting (input, output); (* This program sorts a real one-dimensional array *) VAR n, i, loc : 1..100; x : ARRAY [1..100] OF real; temp : real; (* ********************************************** *) PROCEDURE Exchange; (* Sorts the elements of an array *) BEGIN FOR loc := 1 TO n-1 DO FOR i := loc + 1 TO n DO IF x[i] < x[loc] THEN BEGIN temp := x[loc]; x[loc] := x[i]; x [i] := temp END END; (* Exchange *)
  • 117. (* ********************************************** *) BEGIN (* Main program *) write ('How Many numbers? : '); readln (n); FOR i := 1 TO n DO BEGIN write ('x[',i:3, ']= '); readln (x[i]) END; exchange; writeln (' sorted data: '); FOR i := 1 To n Do writeln (' x[',i:3,']= ', x[i]:4:1); readln END.
  • 118. 12.3 Strings It has been probably though of an string as an array of type "char". This is true with two exceptions: i) Strings use index 0 to store the length byte of the string. ii) Strings always start "char" date at index 1. A string variable is declared in the following way VAR stringname : STRING[length]; or in the following way TYPE stringtype = STRING[length]; VAR stringname : stringtype; Notice that when a string variable is declared, it is usually specified the maximum length that will be needed. Pascal stores string data a little differently than integers or reals. Strings have two parts: i) The number of characters in the string. ii) The actual characters of the string. With the storing of integers and reals it is used an analogy of a box inside the computer.
  • 119. With the storing of strings, think of a series of adjacent boxes. The first box stores the number of characters in the string and is called the "length byte". The remaining boxes store the characters of the string (one character per box). String variables can hold strings as long as 255 characters. This should be more than ample for most applications. Obviously the "length byte" can be computed using function "ord" in the following way". ord (stringname [0]); To obtain the current length of a string it is used function "length": length (stringname); This current length consists only of the number of characters in the string. It does not include the length byte. According to the above remarks if a string variable is declared as STRING[30], then it is told to Pascal to use 31 bytes (do not forget the length byte) to store the string data. If the input string is composed of 5 characters, Pascal still uses 31 bytes. However, the length byte is a "char" value of 5, and the data in STRING[6] through STRING[30] is undefined. The following program illustrates the above remarks and how a string can be treated as an array. The last "writeln" shows how it is usually displayed an string.