Basic PASCAL Programming

Here are some of the basic Pascal elements that we covered in class.

Pascal - Karel comparison
Structure of a Pascal program
Variable Types
Assigning Values to Variables
Formatted Input and Output
Functions
An extended example: Unit Conversion

Pascal - Karel Comparison

Karel: A method to instruct Karel to solve tasks in a virtual world.
PASCAL: A method to instruct the computer to solve tasks in the real world.

Programming for Karel and programming in Pascal are closely related. For example, IF test THEN and WHILE test DO are the same for Karel and Pascal. Also, the general method of programming by starting with the main execution block and refining the program using new instructions is the same in both languages. However, there are a few differences that are listed below.

Karel

Pascal

BEGINNING-OF-PROGRAM
PROGRAM ProgramName;
DEFINE-NEW-INSTRUCTION name AS
PROCEDURE ProcedureName; or
FUNCTION FunctionName;

(details handled later)

BEGINNING-OF-EXECUTION
BEGIN
      turnoff
   END-OF-EXECUTION
END-OF-PROGRAM
END.
Karel can not count or do any computations Pascal can do any mathematical computation and knows about most mathematical functions. Parenthesis can be used, and Pascal knows about the order of operations.
Karel can not remember anything Pascal can remember integers and real numbers, characters, strings, and much more. Everything that should be remembered must be stored in variables.
Names can not include spaces, but they can include the minus sign '-' Names can include neither spaces nor minus signs
You can not use any type of comments for a Karel program. The program should use descriptive names so that it comments itself. You should always use descriptive names inside a Pascal program. However, you can - and should - also use comments to illustrate certain main features of your program.

The Structure of a Pascal Program

Every Pascal program must follow a basic structure. While this structure is very similar to Karel programming, there are several differences. Below is the basic structure that every Pascal program must follow.

PROGRAM ProgramName;

VAR
   VariableName : VariableType;
   VariableName : VariableType;
   ...

PROCEDURE ProcedureName;
   variables here if necessary
BEGIN
    Some Code;
END;

FUNCTION FunctionName(variableList): VariableType;
   variables here if necessary
BEGIN
   Some Code if necessary;
   FunctionName := some expression
   More Code if necessary;
END;

... more functions and procedures if necessary ...

BEGIN
    the main program block. It should be small and all
    work should be delegated to the procedures and
    functions.
    It often consists of a WHILE loop that calls in 
    turn procedures and functions in the appropriate
    order.
END.

Note: The functions and procedures can appear in any order. The only requirement is that if one procedure or function uses another one, that latter one must have been defined already.

Variable Types

There are five basic variable types in Pascal: INTEGER, REAL, CHAR, BOOLEAN, and STRING. They are defined as follows:

INTEGER A positive or negative integer between a smallest (negative) and a largest number. In general the smallest and largest number possible depends on the machine; for IBM PC and Turbo Pascal they are:
smallest Integer: -32766
largest Integer: 32767
REAL Can contain a real number in scientific or decimal notation. There is a limit on the size and accuracy of the real number that will be covered later. Valid real numbers are, for example:
Decimal Notation: 1.234 or -34.5507
Scientific Notation: 5.0E-3 or -7.443E3
CHAR Any key on the keyboard is considered a valid character. Characters are usually enclosed in single quotes. For example: '1' is a character, while 1 is an integer.
BOOLEAN We will deal with boolean variables later
STRING A string is a collection of up to 255 characters enclosed in single quotes. For example: 'Bert' is a string of 4 characters. More details about strings will follow later.

Assigning Values to Variables

Variables are simply a name for a block of memory cells in main memory. If a value is assigned to a variable, that value must be of the same type as the variable, and will be stored in the memory address designated by the variable name. The assignment statement is the semicolon-equal :=.

Variables must be declared at the beginning of the program, a procedure, or a function
Variables must be initialized before they can be used.
Variables can be reused as often as necessary. Their old value is simply overwritten by a new assignment.

Example:

PROGRAM Test;
VAR
   x : REAL;        { variable name is x, type is real
   i : INTEGER:     { variable name is i, type is integer
   c : CHAR;        { variable name is c, type is character
   s : STRING;      { variable name is s, type is string
BEGIN
    x := -34.55;    { valid real number assigned to variable x }
    x := -3.9E-3;   { valid real number assigned to variable x }
    WRITELN(x);     { x contains the value -3.9E-3 }
    i := 10;        { valid integer number assigned to variable i }
    i := i * i;     { valid (!) - i will be 100 now }
    i := 9933;      { valid integer number assigned to variable i }
    i := -99999;    { invalid integer - too small }
    i := 999.44;    { invalid assignment - types do not match }
    c := '1';       { valid character assigned to variable c }
    c := 1;         { invalid assignment - types do not match }
    c := 'Bert';    { invalid assignment - types do not match }
    c := 'd';       { valid character assigned to variable c }
    WRITELN(c);     { c contains the value 'd' }
    d := 'c';       { unknown variable - the variable d is not declared }
    WRITELN(s);     { invalid reference - s has undefined value }
END.

Formatted Input and Output

Reading Information
To read information from the keyboard, you can the command READLN, as in the following example:
PROGRAM Test;
VAR
   x : REAL;               { x is declared to be real }
   i : INTEGER;            { i is declared to be an integer }
   c : CHAR;               { c is declared to be a character }
BEGIN
    READLN(x);             { user can type a real number, followed by
                           the return key. The value will be stored 
                           in the variable x. If the user input is
                           not a real (or integer) number, a
                           runtime error (invalid assignment) will occur. }
    READLN(i);             { user can type a integer, followed by
                           the return key. The value will be stored 
                           in the variable i. If the user input is
                           not an integer, a runtime error (invalid 
                           assignment) will occur. }
    READLN(c);             { user can type any character, followed by
                           the return key. The value will be stored in
                           the variable c and will be a character. If
                           a user enters 1, c will be the character '1'
                           not the integer 1. }
    READLN;                { user can type a single return. }
END.

The exact workings of the READLN command will be discussed later.

Writing Information
To write information on the screen, you can use the WRITE or WRITELN command. You can write the content of variables or simple text. There are several variations:
Writing Text WRITE('any text'); writes any text enclosed in simple quotes on the screen
Writing integers unformatted WRITE(I); I is an integer variable
Writing integers formatted WRITE(I:num); I is an integer and num indicates the total positions to be used. If the value contained in the variable I needs more digits, num is ignored.
Writing reals unformatted WRITELN(x); x is a real variable. Will always write the real number in scientific notation and is almost never what you want.
Writing reals formatted WRITELN(X:num1:num2); X is a real variable, num1 is the total amount of digits to use (including sign and period) and num2 is the number of digits after the period.

Note: The same rules apply for the command WRITELN but this command also positions the cursor to the first position of the next line.

You can combine writting text and more than one variable by seperating the individual components by a comma. Here is an example:

PROGRAM Test;
VAR
   x : REAL;
   i : INTEGER;
   j : INTEGER;
BEGIN
    x := 12.449;
    i := 10;
    j := -300;
    WRITE('This is some text');   
    WRITELN('Unformatted integer ',i);
    WRITELN('Unformatted integer computation ',i*i);
    WRITELN('formatted integer',i:4);
    WRITELN('formatted integer',j:4);
    WRITELN('Unformatted real ',x);
    WRITE('Formatted real');
    WRITE(x:8:2);
    WRITELN('all in one line');
END.

which will produce the following output:

This is some textUnformatted integer 10
Unformatted integer computation 100
formatted integer  10
formatted integer-300
Unformatted real  1.24490000000E+01
Formatted real   12.45all in one line

Functions

Functions provide a flexible method to apply one formula many times to possibly different values. They are comparable to procedures but

functions are of always of a certain type
functions usually have one or more input variable(s)
the function name must appear at least once inside the definition

The general form of the function statement looks like this:

FUNCTION FunctionName(VariableName: VariableType): VariableType;
BEGIN
    some code, if necessary;
    FunctionName := some computation;
    more code if necessary;
END;

Note that every function must contain the function name at least twice: once in the definition of the function, and once to assign the result of a computation to the function. Functions can be used similar to variables. You can assign the result of a function to a new variable, you can print the result of a function using WRITE or WRITELN, or you can use the result of a function in another computation or test. Here is an example:

PROGRAM Test;
VAR
   radius: REAL;

FUNCTION CircleArea(r : REAL): REAL;
BEGIN
    CircleArea := 3.1415 * r * r;
END;

BEGIN
    WRITE('Area of circle with radius 2.0: ');
    WRITELN(CircleArea(2.0):6:1);
    WRITE('Area of circle with radius 5.0: ');
    WRITELN(CircleArea(5.0):6:1);
    WRITE('Enter your own radius: ');
    READLN(radius);
    WRITE('Area of circle with radius ', radius:3:1,': ');
    WRITELN(CircleArea(radius));   { ugly - formatting missing for real }
    radius := 5.0;
    radius := CircleArea(radius);
    WRITELN(radius);               { can you guess the output ? }
END.

An extended example: Unit Conversion

Below is a basic Pascal program. Please look very carefully at it; it can be used as a prototype for many other programs that you will have to write.

PROGRAM A_Basic_Program;
{****************************************}
{* Programmer: Bert G. Wachsmuth        *}
{* Date:       Sept. 28, 1995           *}
{*                                      *}
{* This program converts degree Celcius *}
{* to and from degree Fahrenheit. The   *}
{* user can choose the conversion from  *}
{* a menu.                              *} 
{****************************************}
The beginning of the program. Note that the name of the programmer and the date when the program was finished are part of the comments. Also, a brief description of the program is given.
VAR
   UserChoice : CHAR; { menu choice }
   UserInput  : REAL; { number to convert}
   Answer     : REAL; { converted answer }
The list of variables. There are two real variables, one for the user's input number and one for the converted number. Even if more conversion formulas are added later, only two variables are needed.
{****************************************}
PROCEDURE ShowTheMenu;
{ This procedure shows the available     }
{ options to the user of the program.    }
BEGIN
     WRITELN;
     WRITELN('     A Basic Program');
     WRITELN('     ---------------');
     WRITELN(' a) Celcius to Fahrenheit');
     WRITELN(' b) Fahrenheit to Celcius');
     WRITELN;
     WRITELN(' x) To exit the program');
     WRITELN;
END;
The menu that the user will see. Note the blank line produced by the WRITELN at the top and bottom, as well as the spacing in front to move the text to the middle of the screen.
{****************************************}
PROCEDURE GetUserChoice;
{ This procedure asks the user for their }
{ choice and stores the result in        }
{ UserMenuChoice.      }
BEGIN
    WRITE('Enter your choice:       ');
    READLN(UserChoice);
END;
This procedure asks the user for their choice and stores the result in the variable UserChoice. Note that by using WRITE instead of WRITELN the user's input will appear in the same line as the prompt. Also, the empty space after the prompt will align this letter with the next user input.
{****************************************}
PROCEDURE GetNumberToConvert;
{ Asks the user for the number to be     }
{ converted                              }
BEGIN
   WRITE('Enter number to convert: ');
   READLN(UserInput);
END;
This procedure asks for the number to convert. Again, using WRITE instead of WRITELN will make the user's number appear in the same line as the prompt. The number will be stored in the variable UserInput
{****************************************}
PROCEDURE Wait;
{ Holds execution until user presses     }
{ RETURN                                 }
BEGIN
    WRITE('Press RETURN to continue ...');
    READLN;
END;
A READLN without a variable will wait until the user hits the RETURN key. The keystroke is not stored in any variable.
{****************************************}
FUNCTION ToFahrenheit(x: REAL): REAL;
{ Function to convert degrees Celcius to }
{ degree Fahrenheit.                     }
BEGIN
     ToFahrenheit := 9/5 * x + 32;
END;
This functions converts its input x to degree Fahrenheit. The result of the computation can be used by any other procedure or function, or by the main program.
{****************************************}
FUNCTION ToCelcius(x: REAL): REAL;
{ Function to convert degrees Fahrenheit }
{ to degree Celcius.                     }
BEGIN
     ToCelcius := 5/9 * (x - 32);
END;
This functions converts its input x to degree Celcius. The result of the computation can be used by any other procedure or function, or by the main program.
{****************************************}
PROCEDURE DoTheConversion;
{ This procedure converts the number     }
{ contained in UserInput to the degree   }
{ according to the user's menu choice.   }
BEGIN
     IF (UserChoice = 'a') THEN
        answer := ToFahrenheit(UserInput);
     IF (UserChoice = 'b') THEN
        answer := ToCelcius(UserInput);
END;
This procedure selects the appropriate conversion function depending on the content of the variable UserChoice. In any case, the result of the conversion is stored in the variable answer
{****************************************}
PROCEDURE DisplayTheAnswer;
{ This procedure displays the answer in  }
{ a nice numerical format. It switches   }
{ the title of the table displaying the  }
{ answer depending on the user's menu    }
{ choice.                                }
BEGIN
     WRITELN;
     WRITELN('        Degree');
     IF (UserChoice = 'a') THEN
        WRITELN('Celcius    | Fahrenheit');
     IF (UserChoice = 'b') THEN
        WRITELN('FahrenHeit |   Celcius');
     WRITELN('------------------------');
     WRITE(UserInput:8:2);
     WRITE('   |   ');
     WRITE(Answer:8:2);
     WRITELN;
     WRITELN;
END;
This procedure displays the answer. It is probably the smartest procedure of the whole program. Can you see exactly what it does, and why it is considered a smart procedure ?
{****************************************}
BEGIN
   UserChoice := 'q';
   WHILE (UserChoice <> 'x') DO
      BEGIN
         ShowTheMenu;
         GetUserChoice;
         IF (UserChoice = 'a') OR
            (UserChoice = 'b') THEN
           BEGIN
              GetNumberToConvert;
              DoTheConversion;
              DisplayTheAnswer;
              Wait;
           END;
      END;
END.
The main execution block, or main program. It consists of a simple loop that executes unless the variable UserChoice contains the character x. However, the user is asked for the first time inside the loop, thus the variable UserChoice must be initialized by hand before the loop can start. If a user enters x then many procedures are not needed and are therefore blocked inside the IF statement. Note that the IF statement uses the logical operator OR. Why did we not use the appearently easier form IF (UserChoice <> 'x') THEN ?
(bgw)