• Keine Ergebnisse gefunden

Procedures and Functions

Im Dokument Turbo Pascal® Tutor (Seite 154-163)

In previous chapters, procedures and functions (known collectively as subprograms) were used in some of the sample programs. This chapter describes the concepts behind subprograms and shows how and where to place them in a Pascal program. It also introduces the notion of scope, which determines what the identifiers used in a subprogram mean and where a subprogram can be called from. Finally, it discusses parameters, the data objects a subprogram works on.

Subprograms

You've learned that a Pascal program can be divided into the Big Three: a program heading, a declaration part, and a statement part (or main program). You've also learned that each statement in the main program is normally executed in order-from beginning to end-unless a conditional (if or case) or iterative (for, repeat ... until, or while) statement alters that pattern.

Subprograms allow you to associate an identifier with a series of statements. Once defined, the actions represented by the subprogram can be invoked simply by naming the desired subprogram (calling it).

Here's an example of a situation in which a subprogram might come in handy. The following statement asks the user for a number, then checks the number to see if it is within range. If so, the value entered is assigned to the variable NewNumber.

WriteLn('Please enter an integer from', Minimum, , to " Maximum, ': ');

ReadLn(Temporary); { Temporary is of type Integer}

while (Temporary < Minimum) or (Temporary > Maximum) do beqin

WriteLn('The integer you have entered is out of range.');

WriteLn('Please try again: ');

ReadLn(Temporary);

end;

NewNumber := Temporary; { NewNumber is of type Integer }

Suppose there are several places in your program where you need to perform this function. A crude technique would be to copy all of these statements into each place. While a good text editor like Turbo Pascal's makes this approach feasible, it increases the size of both your source and executable programs and slows down compilations. Worse, if you had to make a change to this number-entry routine, you'd need to find and alter every occurrence.

Fortunately, Pascal (and virtually every other programming language) provides a solution to this problem. Instead of copying the group of statements, you can give it a name and cause the entire group to be executed by mentioning that name. In Pascal, such a group of statements is called either a procedure or a function; both correspond to what BASIC and FORTRAN call subroutines.

We'll look first at procedures; most of what we'll say about them applies to functions as well.

Procedures

To create a procedure, you declare its name as an identifier (as you declare all identifiers), and present the compiler with the code that is to go by that name. The syntax of a procedure declaration is shown in Figure 11.1.

Procedures and Functions 133

procedure declaration ~ procedure heading ~ procedure body ~

procedure heading

procedure body

formal parameter list

inlin.

body

--<

inlin.

T co2):T

Figure 11 .1 : Syntax Diagram of a Procedure Declaration

A procedure declaration begins with the reserved word procedure, followed by the identifier to be associated with that procedure. Then there's an optional list of parameters (which we describe in the next paragraphs) and a semicolon. The body of the procedure follows, and a closing semicolon finishes things off.

A procedure body consists of the same sequence of declaration part/statement part that comes after the heading of a program. About the only difference is that the closing end is followed by a semicolon instead of a period.

A procedure is essentially a mini-program embedded within a larger program. A procedure can declare its own constants and variables, just like a main program. The acid test for "main program likeness" is, Can you declare a procedure from within a procedure? Yes! And you can declare procedures within that procedure, and so on ad infinitum. (Well, not quite.

All compilers cop out this side of infinity; Turbo Pascal permits at least 16 levels-and programs rarely use more than three or four.)

Where do you put procedures in your program? In Standard Pascal, they come after all other declarations (label, constant, type, and variable) and before the opening begin of the main program. Turbo Pascal is more

flexible on this score and lets you place them anywhere in the declaration part.

Let's rewrite our earlier sequence of number-inputting statements as a procedure to show how we might build a small program around it.

program Sample;

WriteLn('inclusive. Please try again.');

ReadLn(Temporary); program Sample's main program

0: WriteLn('You have selected option 0');

25: WriteLn('This is option 25: ');

end;

end.

Procedures and Functions 135

Note that procedure GetNumber's const, type, and var declarations are formatted exactly like those of a Pascal program.

Besides avoiding duplication, procedures make programs easier to write and understand. They allow you to break down big, complicated tasks into a series of smaller, easier tasks. This divide-and-conquer approach is the way to write programs, and if you only carry a single piece of mental baggage away from this book, this should be it.

As a rule of thumb, if a main program is too long to fit on a sheet of paper, it's too long-break it down into one or more procedures. And if one of those procedures ends up being longer than a page, break it down also.

Ultimately you're left with a series of easy procedures that collectively perform a tough job.

In addition, procedures and functions can serve as reusable modules for pasting into new programs.

Changes to procedures instantly affect all parts of the program that call it-without any additional rewriting. Also, when a program involves more than one author, each programmer can write one or more procedures, then combine them into the finished product. This modular approach allows each author to perfect his or her part of the program without having to directly modify the work of others.

Scope

You know that you can't use the same identifier twice in the declaration part of a program. Since it is possible to declare types, constants, and variables in a procedure, you may well ask, What happens if the same identifier is declared in both the main program and a procedure? Or in two procedures?

Well, since each identifier can only refer to one thing, it seems as though the compiler would flag the second use of the identifier as an error.

Type in and check the syntax (Command-Y) of this program. (Don't bother to run it.)

program testl;

const J = 13;

procedure testProcedure;

var

J: Integer;

begin end;

begin end.

If you performed this exercise, you know that no error resulted from redefining 1 in procedure testProcedure. But this next program does produce a Duplicate Identifier error: highest level of the program and a second one at a lower level.

It would be easy to write a compiler that wouldn't accept Testl's declaration of

I.

However, if Pascal worked that way, programming in modules would be difficult. You'd have to keep track of all the identifiers used in a program-and typing errors and other goofs would make it easy to alter variables unpredictably.

To avoid this problem, the concept of scope was developed. Pascal's scope rules specify, in a rigorous way, what object any identifier refers to at a given time. It is scoping rules that enable Turbo Pascal to cope with two identifiers with the same name in program Testl.

Scope Rule #1: Each identifier has meaning only within the block in which it is declared, and only after the point in that block at which it is declared.

Thus, in the previous example, variable Temporary only has meaning within the procedure GetNumber, and even then only after its declaration. By the same rule, the declarations

type

Response = Minimum .. Maximumi {A type for a legal response}

can't occur in the reverse order. If they do, the constants Minimum and Maximum aren't defined when the type Response is defined using them, and the compiler indicates an error.

Another consequence of the first scope rule is that procedure GetNumber has access to variables that were declared before GetNumber in the declaration part of the program Sample. Thus, the statement

NewNumber := TemporarYi

The converse, however, is not true. In the main program, we cannot write the statement

Temporary := NewNumberi

because the variable Temporary is undefined outside of GetNumber.

Temporary is said to be local to GetNumber and is not visible outside that block. By the time the compiler gets around to compiling the statements of the main program, it has forgotten everything it knew about variable Temporary.

Scope Rule #2: If a global identifier is redefined within a block, then the innermost (most deeply nested) definition takes precedence from the point of declaration until the end of the block.

What does this mean? The following program illustrates:

program Ai

identifier I defined in

B integer; This declaration "hides" procedure B within the Statement Part of procedure C. However,

are visible: program), we've listed which identifiers are visible and what they refer to.

To understand how this information is derived, it helps to pretend that you are the compiler, scanning the program from top to bottom. Each time you encounter a definition that overrides a previous one, you make a note of the new definition, and use it until the current block is exited. When you exit a block, all the identifiers declared locally within that block become undefined, and all the identifiers that were temporarily "hidden" by definitions in that block become visible once more.

Exercises

Consider the following program. At each of the points marked { 1 }, { 2 }, and { 3 }, list the identifiers that are accessible and the procedure (or program) where they were defined. For the constant identifiers, also list their values. For the variables and types, list their base types (that is, the predefined type from which their types are derived).

program ScopeTest;

procedure Secondi

Now consider the following program. Will it compile without errors? What will it output to the screen when run? Why? Test your answer using Turbo Pascal. main program, a procedure's local variables are created (assigned places in

Procedures and Functions 141

Im Dokument Turbo Pascal® Tutor (Seite 154-163)