Previous Table of Contents Next


Listing 5.20. A demonstration of recursion and forwards.

  program fig20;

    var
      i: byte;
      result: real;
    function power(x: real; y: integer): real;
      { function: returns result of x^y where x and y are integers }
      { written recursively }
      begin
        if y >= 1 then
          power := x * power(x,y-1)
        else
          power := 1;
      end;

    begin
      for i := 1 to 10 do
        begin
          result := power(i,2);
          writeln(i, ‘ squared is ’, result:0:2);
        end;
    end.

A recursive function, such as the one in Listing 5.20, always has a condition to stop recursion and return some alternate value. In this case, when y becomes 0 when it is called in the function, the value 1 is returned, in signification that when x is anything and y is 0 in a power function, the result is always 1. Figure 5.5 illustrates the variable values and actions when power() is called.


Figure 5.5.  Description of the recursive power function.

With the preceding case, a typical algebra equation is used in the power function: xy. Logically, in algebra, xy= x * xy-1. This continues until y becomes 0; in this case, xy becomes 1, and there is no need to go any further.

5.2.5.4. Prewritten Procedures and Functions

TP, like most programming languages today, comes with a variety of procedures and functions already written to do various things. Among those things are working with files and directories, DOS-related functions, screen output and control, enhanced keyboard input, and working with and manipulating data. You can find a description of many of these prewritten items later in this chapter.

5.2.6. Units, Unit Creation, and Include Files

This section describes TP’s features of modularity. They involve the creation and use of units, as well as use of include files. The prewritten procedures and functions come in the form of units, as well, and those will be described at the end of this section.

5.2.6.1. Units and Unit Creation

A unit is a modular piece of code, with procedures and functions that may be included into any other program or unit to give access to all of the code within. Only the code in the unit that is used, generally, is compiled into the executable. Also, the code is linked into the executable at compile time, not runtime (you do not have to distribute a unit to get an executable file you compile to work).

The files in your \units directory (more than likely) are examples of unit files. These are the less commonly used units, which are included with Turbo Pascal. The more common ones, to be described later, are loaded into memory when the compiler is active. The units are not like object files and are not compatible with object files. They are optimized to a larger degree, in that only the code that is needed is included.

In Listing 5.21, note the format of a unit. Units include procedures and functions, which are generally related, in the entire listing. The interface section lists the headers of the procedures and functions, as well as any data type definitions, constant definitions, and initialization code that may be required to call any of the code that is in the unit. Note that data types cannot be duplicated.

Any type functions that are needed for unit-related functions and procedures must be declared in that unit and that unit only. The implementation section lists all the headers of the procedures and functions again, as well as the code associated with each of the headers. In implementation of a unit, all items in the interface section are made aware of the program, including type and constant declarations. Because Pascal is a strongly typed language, if a type is referred to in two locations with the same name and same description, they are still different.

Listing 5.21. An example of a unit file.

  unit fig21;
  { note, the identifier here must match the name of the file }

    interface
      function power(x:real; y: integer):real;
    implementation
      function power(x:real; y: integer):real;
      { must be exactly as above }
        var
          i: integer;
          result: real;
        begin
          result := 1;
          for i := 1 to y do
            result := result * x;
          power := result;
        end;

   end.

For you to use this unit, or any other unit, it must be specified after the program clause of the code in a uses clause, followed by the exact name of the identifier used in the unit clause of the unit’s code. In Listing 5.22, note how the unit just created is registered and used in the resulting program. The compiled unit, as specified in Listing 5.21, should be made available to this program when created.

Listing 5.22. The use of a unit file in a program.

   program fig22; uses fig21;
   {if more than 1 unit put commas between each id}
     var
       i: byte;
     begin
       for i := 1 to 10 do
         writeln(i, ‘ squared is ’, power(i,2):0:2);
     end.

Here, the program executes in the same manner as Listings 5.19 and 5.20. The advantage here is that, if the unit fig21 is available, the power function does not have to be retyped and retested, just the uses clause must be typed. This kind of modularity and ability to organize code can be very useful. Also, in very large programs, units must be used, as the executable created must have a number of code segments that are a maximum of 64 KB each.

5.2.6.2. Include Files

Another not necessarily better option, but one that may be preferable, is the use of include files. When the compiler option to include a file is issued, the compiler inserts the file specified at that point in the code and compiles the code as if that file were typed in the source originally starting in the exact position the include directive was placed. A file is included into a Turbo Pascal program, at any point, by use of the $I <filename> compiler directive. For example, {$I STRUCT.PAS} is a valid include compiler directive.


Previous Table of Contents Next