Pascal Notes


Contents

  1. Introduction
  2. Getting Started
  3. Pascal
  4. References

Introduction

Pascal was invented in 1971 by Niklaus Wirth as an instructional tool. With very necessary practical extensions, it was adopted as a general purpose programming platform. For example, it formed the basis of the Delphi programming environment created by Borland for Windows programming. This may be regretted, since Pascal erects meaningless hurdles for the programmer, and lacks capabilities for general use. For example, there is not only no exponentiation operator, but no built-in function available for it, as there is in C. Formatting of input and output is very minimal; in basic Pascal, indeed, there is none. Type casting is very limited, to teach programmers the importance of paying attention to type, but a distinct inconvenience in practical work. Pascal emphasizes structured programming, and includes only the essentials, so good programming practices are encouraged.

Pascal is named in honor of Blaise Pascal (1623-1662), a mathematical prodigy, born in Clermont-Ferrand. In 1642 he created the first mechanical adding machine. In Physics, he is best known for demonstrating that the mercury in a barometer is supported by the pressure of the air, not by any attraction of the vacuum, by taking a barometer up a mountain. The SI unit of pressure, the pascal or N/M2, is named after him.

Pascal strongly deprecates the use of the "goto" instruction, showing that it can be eliminated by structural programming, so that programs can be quickly and easily interpreted. This is very often misinterpreted by programming novices in assuming that "goto" is somehow a bad thing. In fact, Pascal does offer a "goto" instruction as a convenient feature, only discouraging its misuse. In machine language programming, the "goto" is the only way to affect the flow of execution. In a repetitive structure, such instructions send execution back to the start of the loop, or exit the loop, as required. A flow chart is very often necessary for the understanding of a machine language program, since the program itself is not easily comprehended, largely because of these jumps to sometimes distant locations. Structured programming, with things like WHILE ... DO constructs, make program flow and meaning evident at a glance, and this is why they should be used. The "goto"'s are still there, but are now hidden from the programmer. What Pascal says is that with the programming structures made available, there is no need to construct them with "goto"'s and conditional statements, and consequently to obscure the meaning of the program. A programming language like BASIC, or the original FORTRAN, which are similar to machine language in structure, needs the "goto" to create its programming structures.

The strong typing in Pascal, and the block structure of a Pascal program with its complicated identifier scoping, are both teaching features that become inconveniences in serious programming (however, many people prefer having such features to keep them in line).

Getting Started

The Pascal that I shall use here is the remarkable Turbo Pascal, version 3.0, brought out by Borland in 1985. Turbo Pascal appeared in 1983. It was the first "Integrated Development Environment" for PC's, including an Editor, Compiler, Linker and Debugger in one package. The whole system occupies only 280 KB on a single floppy disk. It is remarkable that this program, which talks about CP/M-86 and CP/M-80, and monochrome adapters, still works well. Here's how to get it running in Windows 98.

I got the MS-DOS prompt from Start, then went to the root with cd \, where I made a directory tpas with md tpas. Then I made tpas the current directory with cd tpas. I put the distribution diskette in drive A: (the original diskette had been copied to a 1.44MB diskette) and executed copy a:\*.* . to copy all the files into C:\tpas. The next step is to run TINST to set the screen display. To do this, just run TINST and press S, and then 2, for an 80x25 text screen display. It is not necessary to install editor commands, since the arrow keys and such will automatically be recognized, so just press Q to quit TINST.

Now enter TURBO and the main screen will appear, with the initial letters of the commands highlighted in yellow. Type W to establish a work file. If you type in HELLO.PAS, a work file of this name will be created in \tpas. You do not need a main file at this point. To start the editor, type E (no is necessary after these letter commands). Type in the following program:

program Hello;
begin
    Writeln('Hello, world!');
end.

Exit the editor with ^K-D (hold down Ctrl and type K D). When you press the menu will appear again. Type S to save the work file. Type C to compile the work file; this should be successful. If not, you can always go back to the editor and fix what is wrong, then return, saving the work file as before. Now press R, and TURBO will print Running. On the next line should be the output of your program. When you press again, you will return to the menu.

Pascal

If you are new to Pascal, the first thing to do is to read Jensen and Wirth, and then to try out the examples there, and in addition those you can construct for yourself, when you have Pascal available. A "Hello, world!" program has already been presented, and if you can get this to run, you are ready to experiment with Pascal.

A Pascal program begins with a line like program Hello; that has very little effect, only providing a name like Hello. The name Hello can be followed by the names of files used, such as (Input, Output), but these files are opened automatically in most Pascals and do not need to be specified. This line is then followed by a block. At the end of the block is a ".". This "." comes only at the end of the program, not at the end of every block. Other blocks will usually end with a ";". A block may be nested within a block, and functions and procedures may be defined externally if desired. A block begins with declarations and definitions, and ends with a compound statement delimited by begin and end, which have the same effect as { and } in C.

The declarations are label, const, type, var, procedure and function, legally in that order, but in Turbo Pascal they can be in any order, as identified by these reserved words. Pascal is case-independent, so upper and lower case can be used as seems best to the programmer. The words shown here in boldface are reserved words, and can be used in no other way. They are not written as boldface in programs. For simple programs, you will only need const and var declarations. A const declaration is of the form identifier = value;, as n = 10; This provides descriptive names for constant quantities, and allows them to be changed easily, no matter how many times they are used. After the word const, as many const declarations can occur as necessary. A var declaration declares a type, in the form identifier : type;, as n : Integer. The basic types available are Integer, Real, Boolean and Char. Integers are signed 16-bit quantities ranging from +32,767 to -32,768. Reals should have a decimal point with a digit preceding and following, or be expressed in scientific notation, as 1.25E6. Reals have about 11 significant figures in the mantissa, and a range of 10±38. Boolean includes the values True and False, with False < True in comparisons. Chars are 1 byte in size, ordered by their ASCII values.

Following the declarations is a compound statement between begin and end, consisting of a series of statements separated by semicolons. Be careful of using excess semicolons, since they may represent a null statement which usually is of no importance, but sometimes can be significant. No semicolon is required between the end of the last statement and end, for example, but one here will do no harm. In other cases, an extra ; can terminate a statement long before you desire.

The assignment statement is very common. Its form is variable := expression. Note that := is used, not =, which is an operator of comparison. a := b copies the value of variable b into variable a, while a = b returns True if the values of a and b are equal, and False otherwise. The type of the variable must be the type returned by the expression, except that Integers can be assigned to Reals (but not vice versa). To convert a Real to an Integer, you must specify Round(x) or Trunc(x). This lack of automatic type casting is to discipline the programmer, but is nonetheless annoying when it would be appropriate.

Arithmetic on Integers is done with the binary operators +, -, *, div and mod. In division, div returns the quotient and mod the remainder, both Integers. Arithmetic on Reals is done with +, -, * and /. Integers can be divided by /, but the result is Real. If Integers and Reals are mixed, everything is converted to Real. The functions Abs(x) and Sqr(x) return Integers if the argument is an Integer, but Real if the argument is Real. Sqr(x) is x2, while Abs(x) strips off a minus sign. Other than this, for Reals you have Sin(x), Cos(x), ArcTan(x), Exp(x), Ln(x) and Sqrt(x), a limited but generally sufficient set. There is also Frac(x) and Int(x) that return the fractional and integral parts of a Real as a Real. Chr(n) is a Char, where n is Integer. Odd(n) returns True if n is odd, False if n is even.

Simple input and output is very easy in Pascal. Write('x = ', x) will display x on the screen, preceded by "x = ". Writeln('x = ', x) will do the same, but end with a carriage return and line feed, going to the next line. Writeln() just goes to the next line. Read('Enter x: ', x) will print the prompt "Enter x: " on the screen and then wait for you to type in a number, ending with a return (Enter key). This is much simpler than in C, where you have to master the complexities of scanf() and printf() before you can input and output numbers. On the other hand, you have little control over the format of the output.

There is a little more control over output to the screen than indicated above. A statment Write(x : 10 : 4) will write a minimum of 10 characters (the field width, including blanks), and will write the Real variable x right-justified in fixed point with 4 places after the decimal point, with leading blanks. If the last field is omitted, the output will be in exponential ("scientific") notation.

Now you can write many programs that do calculations, but it would be nice to add repetitive execution. As in FORTH, C and FORTRAN, the for statement is appropriate. It takes the form for I := 1 to 10 do. The statement to be iterated follows do, and it is usually a compound statement between begin and end. If you put a ; after do, then this null statement will be executed instead, and what you wanted to repeat will be done only once. The increment can be -1 instead of +1 if you replace to with downto. The loop counter I, or whatever you choose to call it, must be declared in a var declaration. It is normally Integer, or a type derived from Integer. In particular, Real cannot be used.

Choices can be made with an if statement. It takes the form if (Boolean expression) then (statement 1) else (statement 2). If the Boolean expression evaluates to True, then statement 1 is executed. If it evaluates to False, statement 2 is executed. Aftre this, execution passes to the next statement. A Boolean expression combines Boolean values obtained from comparisons with and, or and not, using parentheses as necessary. The comparison operators compare two values with the operators =, <>, >=, <=, > or < which work with any type, and give Boolean values. The connective xor is also defined in Turbo Pascal, and is equivalent to <>. I presume that you already know how to write Boolean expressions.

If a selection is to be made among a number of choices, the case statement is appropriate. Its form is case (expression) of a: (statement 1); b: (statement 2); ... z: (statement 26); end. a, b, ..., z are possible values of (expression), usually integers or chars in the form 'a', 'b' and so on. The (expression) cannot be Real. If none of the labels match the value of the expression, then nothing is done. Unlike in C, execution does not fall through to the next label. The labels are not declared, and cannot be jump targets. case is much more efficient than nested if's because it is a natural structure in machine language.

Boolean statements are used in the program loop structures while (Boolean expression) do (statement) and repeat (statement) until (Boolean expression). In both cases, (statement) is iterated, but the test comes at the top of the loop in a while, and at the bottom of the loop in repeat. Be careful not to introduce extra semicolons! There is no break or continue in Pascal; you must use goto. To do this, declare the label in label 10;, for example. In that block, you can then use goto 10. In standard Pascal, a label can only be up to four digits; in Turbo it can be any identifier.

An array of values is declared like this: a : array[1..10] of Integer;. The array identifier is a, and any element is a[i], where i is between 1 and 10. A two-dimensional array or matrix is declared, for example, as array[1..10,1..10] for a 10 x 10 matrix. The indices can start from 0 or any other value. The limits can be consts as well. Arrays can be declared as types to reduce typing, but this is only a convenience.

Strings of characters are very important in programming, so Turbo Pascal extends basic Pascal to include convenient ways of handling them. A string constant is characters between ' delimiters, as 'this is a string'. If you want an apostrophe in the string, use two apostrophes, as 'Mary''s little lamb'. A string variable is declared as MyString : string[15], for example. This variable occupies 16 bytes in memory, containing 15 Chars and the length of the string, which is at most 15. The individual characters are accessed as MyString[i], where i is the index, and the first character has i = 1. MyString[0] contains the length. A string constant can be assigned to a string variable, as MyString := 'Hallelujah!'; The length of MyString will then be 11. If the string assigned is too long, it will be truncated at 15 characters. Strings may be compared, and concatenated with the operator "+". The length of a string is given by the function Len(string). The function Pos(str1,str2) returns an integer that is the location of str1 in str2. If st1 is not found, 0 is returned. Copy(string,i,n) returns a string that consists of n characters from string, beginning at string[i]. Only characters in the string are returned. Delete(string,i,n) removes n characters from string, beginning at string[i]. Insert(string1, string2,i) inserts string1 in string2 beginning at string2[i]. String variables in Pascal are exactly the counted strings in FORTH.

Comments are placed between curly braces in Pascal, as {this is a Pascal comment}. They are considered the same as blanks or newlines as separators. Curly braces are not used for any other purpose in Pascal. It is also possible to use (* and *) instead. Although this was intended for systems without curly braces, the alternative symbols are useful for commenting out code that contains {} comments.

Procedures and functions are subroutines that may be defined at the start of the program block. Functions return a value, and must be typed, but procedures do not. A procedure is defined similarly to a program. It begins with a line naming it, as procedure Greetings;. Note that the declaration ends with a semicolon. This is followed by a body consisting of declarations and definitions followed by a compound statement between begin and end. A simple procedure is procedure Greetings; begin Writeln('Hello, all!') end; If this procedure is called in the main program by the word Greetings, its message is printed on the screen.

A function definition example is: function Unity : Integer; begin Unity := 1 end;. This function returns an Integer. In the function, the returned value is assigned to the name of the function. It can be used in the main program as, for example, n := Unity. Unlike in C, Unity is not followed by empty parentheses as Unity(); in Pascal, Unity is recognized as a function from its name declaration. Variables defined in the outer block (in the main program declarations) are accessible in procedures and functions defined in the block. If the main program contained a declaration x : Real;, either Greetings or Unity could contain a statement like x := 3.5 that would change the value of x in the program. This is called a side effect of the execution of the procedure or function. Side effects are frowned upon in Pascal, since they may not be evident.

Values may be passed to subroutines by parameters in a list following the name. The formal parameters are declared when the subroutine is defined. When it is called, the place of the formal parameters is taken by the actual parameters, which must be of the declared type. For example, the procedure declared as Funny(p : Real) may be called as Funny(x), where x is a Real variable. The formal parameter is p, the actual parameter is x. When a parameter is declared in this way, a copy of the actual parameter is furnished to the procedure. This value may be used in any way desired, but any changes to the variable in the procedure have no effect on the actual variable. This pass by value protects variables against inadvertent changes when they are passed to subroutines. C passes parameters in the same way.

If a formal parameter is declared preceded by var, then the address of the actual parameter is furnished to the subroutine, and changes to the parameter in the subroutine are changes to the actual parameter itself. If we define procedure Funny(var p : Integer); begin p := -2*p end;, then when it is called as Funny(n), n becomes the negative of twice its value. In this way, procedures can affect variables. Functions usually return a value instead of changing their parameters, but they, too, can use var parameters. This may be considered a side effect, but one that is more visible than something hidden in the subroutine. The equivalent in C is passing a pointer to the variable, which allows modification of the variable itself.

A subroutine must be defined before it is used. If two subroutines call each other, the Catch-22 is resolved with a forward definition, like procedure Funny(x : Real); forward; Now Funny can be used in defining a procedure, and then defined subsequently. The actual definition is procedure Funny; (block). It is not necessary to repeat the parameter list, since it has already been given in the forward definition.

Pointers are used in Pascal in a completely different way than in C. There is no way to find the pointer to an ordinary variable, nor to dereference the pointer to find the corresponding variable. Pointers in Pascal are used to identify dynamically created data structures, like pointers to structures in C. The upward arrow shown in Jensen and Wirth identifying pointers is represented by ^ in Turbo Pascal. In Pascal, structures are called records, and an element pointed to by p is written p^.x, for example, where C would have p-->.x. An undefined pointer is nil, while the memory allocation function new(p) reserves storage and intializes p. The function dispose(p) releases allocated memory. Unless you work with records, it is not necessary to learn about pointers.

Text files are not difficult to work with in Turbo Pascal. Let's see how to read a text file. Use Notepad to make a text file of a few lines, and save it in C:\tpas. If you press Enter after the last line, an empty line will be added to the file. This is, of course, no problem, but should be realized. This file consists of lines ending in , such as are written by Writeln. The first thing to do is to declare a file variable, such as FilVar: Text;. A buffer is necessary for the file name, say FileName: string[14], which is enough to handle a file name without a path. A buffer is also necessary to put a line in temporarily that has been read, say Line: string[81];. We'll just read each line from the file and print it on the screen. If you can do this, you could use the line in any way you wished. The program is:

program Readfile;
var
  FilVar: Text;
  Line: string[81];
  FileName: string[14];

begin
  Write('Filename');
  Readln(FileName);
  Assign(FilVar,FileName);
  Reset(FilVar);
  while not Eof(FilVar) do
  begin
    Readln(FilVar,Line);
    Writeln(Line);
  end;
  Close(FilVar);
end.

The filename is assigned to the file variable by Assign. Reset then opens an existing file for reading or writing. Rewrite would open a new file for writing, erasing an existing file of the same name. Now we read lines with Readln, which reads up to the at the end of each line. Then we display the line on the screen, and go back to read the next line, until the last line has been read and Eof returns True. Finally, we Close the file. Since all files are closed when the program exits, this is not really necessary in this case, but in general files should be closed when you are through with them to put them in order and free up file handles, which are a limited resource. Files can be erased with Erase(FilVar) and renamed with Rename(FilVar,string).

Readln will also read numbers into variables, formatting the text line automatically. These numbers should be separated by blanks. When Readln has satisfied its appetite, it will go to the next line, ignoring anything that may remain. Writeln will write numbers to the text file just as it writes them to the screen. In any case, the file must be in the format expected by Readln for successful results.

The Integer functions FileSize(FilVar) and FilePos(FilVar) return the file size and the current position of the file pointer for reading and writing, respectively. Seek(FilVar,n) moves the file pointer to position n. If you want to append to a file, use Seek(FilVar,FileSiz(FilVar)) after Reset. These functions do not apply to text files, only to files of identical elements. Such files are declared as Numfile: file of Real;, for example (though usually as files of more complex records). Text files are not random access; only the beginning and the end are identifiable. For text files, use SeekEof(FilVar) instead to go to the end of a file for appending.

References

K. Jensen and N. Wirth, User Manual and Report, 2nd ed. (New York: Springer-Verlag, 1974).

Turbo Pascal 3.0, Reference Manual (Scotts Valley, CA: Borland International, 1985). This is not a Pascal textbook, and does not include many examples, but is an indispensable resource.


Return to Math Index

Composed by J. B. Calvert
Created 28 August 2004
Last revised