Previous Table of Contents Next


Listing 5.18. A demonstration of writing and using procedures.

  program fig18;

    { two-level array demonstration rewritten as a procedures
      demonstration determinant of a 3X3 matrix. The general
      formula is for a matrix of:
      [ A B C ]
      [ D E F ] is AEI + BFG + CDH - CEG - BDI - AFH = determinant
      [ G H I ]
    }

    type
      matrixtype = array[1..3,1..3] of integer;
    var
      matrix: matrixtype;
      result: longint;

    procedure loadmatrix(var thematrix: matrixtype);
      { var must be in front of declaration above so matrix
        declarations can survive end of procedure }
      begin
        thematrix[1,1] := 3;
        thematrix[1,2] := 4;
        thematrix[1,3] := 2;
        thematrix[2,1] := 8;
        thematrix[2,2] := 7;
        thematrix[2,3] := 3;
        thematrix[3,1] := 1;
        thematrix[3,2] := 0;
        thematrix[3,3] := 4;
      end;

    procedure determinant(thematrix: matrixtype;
                            var theresult: longint);
    { local variables defined: scope is only within procedure
      determinant }
      var
        x, y, postx, posty1, posty2: byte;
        subadd1, subadd2: longint;
      begin
        for y := 1 to 3 do
          begin
            posty1 := y;
            posty2 := y;
            subadd1 := 1;
            subadd2 := 1;
            for postx := 1 to 3 do
              begin
                if posty1 = 3 then
                  posty1 := 1
                else
                  posty1 := posty1 + 1;
                if posty2 = 1 then
                   posty2 := 3
               else
                   posty2 := posty2 - 1;
                subadd1 := subadd1 * thematrix[postx, posty1];
                subadd2 := subadd2 * thematrix[postx, posty2];
              end;
            theresult := theresult + subadd1 - subadd2;
          end;
     end;

   begin
     loadmatrix(matrix);
     determinant(matrix, result);
     writeln(‘The determinant is: ’, result,    ‘.’);
              end.

5.2.5.2. Functions

Functions, in most ways, are exactly like procedures in that the same rules of programming for procedures apply for functions. The only difference is that the function itself returns a value, a number, character, string, or pointer. Therefore, whether a variable is changed and survives in the parameter list is of no concern, as the parameter list should only contain input values.

Functions, when defined, start with the reserved word function and then a parameter list, as with procedures. The final part is a : followed by a data type that the function will return when enacted. An example of a function is shown in Listing 5.19. Functions may be used exactly in place of where a value might be, as that data type, and in that sense they function as variables of the data type they return, though some input values and code exist to evaluate or return the value.

Functions can have great value in simplifying and streamlining the coding process. Though it is hard to describe when to use functions over procedures, when you gain some slight experience in coding, the situations to use functions will become evident.

Listing 5.19. A demonstration of function use.

  program fig19;

    var
      i: byte;

    function power(x: real; y: integer): real;
      { function: returns result of x^y where x and y are integers }
      var
        i: integer;
        result: real;
      begin
        result := 1;
        for i := 1 to y do
          result := result * x;
        power := result;
      end;

   begin
     for i := 1 to 10 do
       writeln(i, ‘ squared is ’, power(i,2):0:2);
       { function call is treated exactly like a real number }
   end.

5.2.5.3. Recursion, Stack Space, and Forward Declarations

Turbo Pascal has the capability of recursion, or the ability to execute a function or procedure within itself. Pascal recurses completely because the variables that are placed in the parameter list are recopied onto the stack along with the data to completely execute the procedure or function. In this sense, a procedure or function is called exactly the same way in a recursion action as in an iterative action.

The preference is toward iteration (linear programming) instead of recursion if the algorithm could be expressed equally well in the same way. Iteration is faster and generally easier understood than recursion. But where an iterative solution may grow messy or less elegant in nature than a recursive function, recursion may be ideal. Recursion can be seen as splitting up a large problem into several smaller problems of the same nature.

In using recursion, tremendous amounts of stack space could be used, as a recursive function or procedure could recurse many times. Hence, adjustment of the stack space may be desired. That and many other purposes are gained by adjusting values from the default in the $M compiler directive.

It is expressed by stating $M in a comment and then adding three numbers (expressed in a number of bytes). The first is the amount of stack space allowed, the second is the minimum amount of heap needed, and the third is the maximum amount of heap space needed. For concerns of this section, the first number is described. This is the amount of stack space allowed for the program. This is execution space, used for the program itself. When a procedure or function is executed, stack space lessens. The normal default for stack space is 16 KB, the minimum is 0 KB, and the maximum is 64 KB. An example of the proper way to use the $M compiler directive is as follows: {$M 32767,0,655360}. It should appear at the beginning of the code.

In recursion between functions, if the case exists, forward declarations might be useful. A forward declaration is a statement that simply declares the existence of a function or procedure and its appearance. Forwards might be useful when “function a” might call “function b” and “function b would call function a.” Because the compiler has to be aware of a procedure or function before its use, this case might present a problem. Therefore, a forward declaration could be useful.

A forward declaration is made by declaring the header of the procedure/function and then, after the semicolon, stating the reserved word forward, following that with another semicolon. When the actual block of code can occur, the keyword procedure or function is given and then the name and a semicolon.

Listing 5.20 demonstrates a function written to operate recursively. A description of the execution path of the function, which is an integer power function just like the one in Listing 5.19, appears after the listing.


Previous Table of Contents Next