Movatterモバイル変換


[0]ホーム

URL:


Jump to content
WikibooksThe Free Textbook Project
Search

Pascal Programming/Routines

From Wikibooks, open books for an open world
<Pascal Programming

In the opening chapterroutines were already mentioned.Routines are, as it was described before, reusable pieces of code that can be used over and over again.Examples of routines areread / readLn andwrite / writeLn.You can invoke,call, these routines as many times as you want.In this chapter you will learn

  • how to define yourown routines,
  • the difference between a definition and declaration, and
  • the difference between functions and procedures.

Different routines for different occasions

[edit |edit source]

Routines come in two flavors.In Pascal, routines can either replace statements, or they replace a (sub‑)expression.A routine that can be used where statements are allowed is called aprocedure.A routine that is called as part of an expression is afunction.

Functions

[edit |edit source]

Afunction is a routine that returns a value.Pascal defines, among others, a functionodd.The functionodd takes oneinteger-expression as a parameter and returnsfalse ortrue, depending on the parity of the supplied parameter (in layman terms that means whether it is divisible by 2).Let’s see the functionodd in action:

programfunctionDemo(input,output);varx:integer;beginwrite('Enter an integer: ');readLn(x);ifodd(x)thenbeginwriteLn('Now this is an odd number.');endelsebeginwriteLn('Boring!');end;end.

Odd(x) is pronounced“odd of x”.First, the expression in parentheses is evaluated.Here it is simplyx, the variable’s value to be precise, but a more complex expression is allowed too, as long as it eventually evaluates to aninteger-expression.Thevalue of this expression, theactual parameter, is then handed to a (in this case invisible) block of code that processes the input, performs some calculations on it, andreturnsfalse ortrue according to the calculation’s findings.The function’s returned value is ultimately filled in in place of the function call.You can, in your mind, readfalse / true in place ofodd(x), although this is dynamic depending on the given input.

Caution
You are only allowed to call functions where you can put an expression. The following program is wrong:
programlostFunction;beginodd(42);end.
Calling a function results in an expression, in this particular case (the value)false. Butfalse is not a statement. You can only putstatements betweenbegin andend, no expressions.[fn 1]

Procedures

[edit |edit source]

Procedures on the other hand cannot be used as part of an expression.You can only call procedures where statements are allowed.

Caution
A routine can either be a function or a procedure. In some programming languages the routine used to retrieve data from the console can be used like a function, but this is not the case in Pascal. The followingprogram will not compile:
programstrayProcedure(input,output);beginifreadLn(input)=''thenbeginwriteLn('Error: No input supplied.');end;end.
ReadLn refers to aprocedure thus it does not return anything, yet at this specific position a value has to be inserted so theif‑branch language construct and the equal comparison make sense.

Effects

[edit |edit source]

Aprocedure may use functions, and the other way around.Do not understand afunction as a mere substitute for an expression.In the following section we will learn why.

Rationale

[edit |edit source]

The dichotomy of routines, distinguishing between aprocedure and afunction, is meant to gently push the programmer to write “clean” programs.Doing so, a routine does not conceal whether it is just a replacement for a sequence of statements or shorthand for a complex, difficult to write out expression.This kind of notation works without introducing nasty pseudo types like, for example,void in the C programming language where every routine is a function, but the “invalid” data typevoid will allow you to make it (in part) behave like aprocedure.

Definition

[edit |edit source]

Defining routines follows a pattern you are already familiar with since your very firstprogram.Aprogram is, in some regards, like aspecial routine:You can run it as many times as you want throughOS-defined means.Aprogram’s definition looks almost just like a routine’s.

A routine is defined by,

  1. a header, and
  2. a block

in that order.The routine header shows a couple differences depending on whether it is afunction orprocedure.We will first take a look at blocks, since these are the same for both types of routines.

Block

[edit |edit source]

Ablock is the synthesis of a productive part (statements) and (optional) declarations and definitions.In Standard Pascal (as laid out by theISO standard 7185) a block has a fixed order:[fn 2]

  1. constant definitions (theconst-section)
  2. type definitions (thetype-section)
  3. variable declarations (thevar-section)
  4. routine declarations and definitions
  5. sequence (beginend, possibly empty)

All items but the last one, the productive part, are optional.

NoteSections (const,type, orvar-section) may not be empty. Once you specify a section heading, you have to define/declare at least one symbol in the just started section.

InEP, the fixed order restriction has been lifted.There, sections and routine declarations and definitions may occur as many times as needed and do not necessarily have to adhere to a particular order.The consequences are detailed in thechapter “Scopes”.For the remainder of this book we will refer toEP’s definition ofblock, because all major compilers support this.Nevertheless, the order defined by Standard Pascal is a good guideline:It makes sense to define types, before there is a section that may use those types (i. e.var-section).

Header

[edit |edit source]

A routine header consists of

  1. the wordfunction orprocedure,
  2. an identifier identifying this routine,
  3. possibly a parameter list, and,
  4. lastly, in the case of functions, the data type of an expression a call to this function results in, theresult data type.

The parameter list for routines also defines the data type of every single parameter.Thus, the header of the functionodd could look like this:

functionodd(x:integer):Boolean;

Take notice of the colon (:) after the parameter list separating the function’s result data type.You can view functions as sort of special variable declaration which also separates an identifier with a colon, except in the case of a function the “variable’s” value is computed dynamically.

Formal parameters, i. e. parameters in the context of a routine header, are separated by a semicolon.Consider the following procedure header:

procedureprintAligned(x:integer;tabstop:integer);

Note that every routine header is terminated with a semicolon.

Body

[edit |edit source]

While the routine header tells the processor (usually a compiler), “Hey, there’s a routine with the following properties: […]”, it is not enough.You have to “flesh out”, give the routine abody.This is done in the subsequent block.

Inside the block all parameters can be read as if they were variables.

Function result

[edit |edit source]

In the sequence of the block defining a function there is automatically a variable of the function’s name.You have to assign a value exactly one time, so the function, mathematically speaking, becomes defined.Confer this example:

functiongetRandomNumber():integer;begin// chosen by fair dice roll,// guaranteed to be randomgetRandomNumber:=4;end;

Note that the block did not contain avar-section declaring the variablegetRandomNumber, but it is already implicitly declared by the function’s header:Both the name and the data type are part of the function header.

Declaration

[edit |edit source]

A routine declaration happens most of the time implicitly.Declaring a routine, or in general any identifier, refers to the process of giving the processor (i. e. usually a compiler) information in order to correctly interpret your program source code.This information is not directly encoded in your executable program, but it is implicitly there.Examples are:

  • A variable declaration tells the processor to install proper provisions in order to reserve some memory space. This chunk of memory will be interpreted according to its associated data type. However, neither the variable’s name, nor the data type are in any way stored in your program. Only the processor knows about this information as it is reading your source code file.
  • A routine header constitutes a routine declaration (which is usually directly followed by its definition[fn 3]). Here again, the information given in a routine header are not stored directly in the executable file, but they ensure the processor (the compiler) will correctly transform your source code.
  • Likewise,type declarations merely serve the purpose of clean and abstract programming, but those declarations do not end up in the executable program file.[fn 4]

Declarations make an identifier known to denote a certain object (“object” mathematically speaking).Definitions on the other hand will, hence their name, define what this object exactly is.Whether it is a value of a constant, the value of a variable, or the steps taken in a routine (the statement sequence), data defined through definitions will result in specific code in your executable file, which may vary according to the information given in related declarations;writing a variable possessing the data typeinteger is fundamentally different than writing a value of the typereal.The code for properly storing, calculating and retrievinginteger andreal values differs, but the computer is not aware of that.It just performs the given instructions, the circumstance that a certain set of instructions resemble operations on Pascal’s data typereal for instance is, so to speak, a “coincidence”.

Calling routines

[edit |edit source]

Routing

[edit |edit source]

Routines are selected based on their signature.A routine signature consists of

  1. the routine’s name,
  2. the data type’s of all arguments, and
  3. (implicitly) their correct order.

Thus the signature of the functionodd readsodd(integer).The function namedodd accepts oneinteger value as thefirst (and only) argument.

NoteIn some other programming languages the data type of the returned value also belongs to a routine’s signature. Remember differing definitions of the termsignature should you ever switch between programming languages.

Overloading

[edit |edit source]

Pascal allows you to declare and define routines of the same name, but differing formal parameters.This is usually calledoverloading.When calling a routine there must be exactly one routine of that name that accepts parameters with their corresponding data types.

Pre-defined routines

[edit |edit source]
Pascal’s pre-defined functions (excerpt)
signaturedescriptionreturned value’s type
abs(integer)absolute value of argumentinteger
odd(integer)parity (is given value divisible by two)Boolean
sqr(integer)the value squaredinteger

Persistent variables

[edit |edit source]

Some compilers, such as theFPC, allow you to use constants as if they were variables, but different lifetime.In the following example the “constant”numberOfInvocations exists for the entire duration of program execution, but is only accessible in the scope it was declared in.

programpersistentVariableDemo(output);{$ifDef FPC}// allow assignments to _typed_ “constants”{$writeableConst on}{$endIf}procedurefoo;constnumberOfInvocations:integer=0;beginnumberOfInvocations:=numberOfInvocations+1;writeLn(numberOfInvocations);end;beginfoo;foo;foo;end.

The program will print1,2,3 for every call.Lines 2, 4, and 5 contain specially crafted comments that instruct the compiler to support persistent variables.These comments are non-standard, yet some are explained in the appendix,chapter “Preprocessor Functionality”.

Note, the concept of typed “constants” is not standardized.Someobject-oriented programming extensions will give nicer tools to implement such behavior as demonstrated above.We primarily explained the concept of persistent variables to you, so you can read and understand source code by other people.

Benefit

[edit |edit source]

Routines can be used as many times as you want.They are no tools of mere “text substitution”:The definition of a routine isnot “copied” to the place where it is called, the call site.The size of the executable program file remains about the same.

Utilizing routines can also be and usually is beneficial to the development progress of a program.By splitting up a programming project into smallerunderstandable problems you can focus on solving isolated issues as part of the big task.This approach is known asdivide and conquer.We now ask you to slowly shift toward thinkingmore about your programming tasksbefore you start typing anything.You may need to spend more time on thinking about, for example, how to structure a routine’s parameter list.What information, what parameters, does this routine require?Where and how can a recurring pattern be generalized through a routine definition?Identifying such questions needs time and expertise, so do not be discouraged if you are not seeing everything the task’s sample answers show.You will learn through your mistakes.

Keep in mind, though, routines are no panacea.There are situations, very specific situations, where you do not want to use routines.Recognizing those, however, is out this book’s scope.For the sake of this textbook, and in 99% of all your programming projects you want to use routines if possible.Modern compilers can even recognize some situations where a routine was “unnecessary”, yet the only gain is that your source code becomes more structured and thus readable, albeit at the expense of being more abstract and therefore complex.[fn 5]

Tasks

[edit |edit source]
Write a (now infamous) program that writes the word “Mississippi” in large (spanning at least three lines) capital letters. It should become apparent that writing four routines,printM,printI,printS,printP, will significantly speed up development.
An acceptable answer could look like this
programmississippi(output);constwidth=8;procedureprintI;beginwriteLn('#   ':width);writeLn('#   ':width);writeLn('#   ':width);writeLn('#   ':width);writeLn('#   ':width);writeLn;end;procedureprintM;beginwriteLn('#    #':width);writeLn('##  ##':width);writeLn('# ## #':width);writeLn('#    #':width);writeLn('#    #':width);writeLn;end;procedureprintP;beginwriteLn('###  ':width);writeLn('#  # ':width);writeLn('###  ':width);writeLn('#    ':width);writeLn('#    ':width);writeLn;end;procedureprintS;beginwriteLn('  ###  ':width);writeLn(' #   # ':width);writeLn('  ##   ':width);writeLn('#   #  ':width);writeLn(' ###   ':width);writeLn;end;beginprintM;printI;printS;printS;printI;printS;printS;printI;printP;printP;printI;end.
An acceptable answer could look like this
programmississippi(output);constwidth=8;procedureprintI;beginwriteLn('#   ':width);writeLn('#   ':width);writeLn('#   ':width);writeLn('#   ':width);writeLn('#   ':width);writeLn;end;procedureprintM;beginwriteLn('#    #':width);writeLn('##  ##':width);writeLn('# ## #':width);writeLn('#    #':width);writeLn('#    #':width);writeLn;end;procedureprintP;beginwriteLn('###  ':width);writeLn('#  # ':width);writeLn('###  ':width);writeLn('#    ':width);writeLn('#    ':width);writeLn;end;procedureprintS;beginwriteLn('  ###  ':width);writeLn(' #   # ':width);writeLn('  ##   ':width);writeLn('#   #  ':width);writeLn(' ###   ':width);writeLn;end;beginprintM;printI;printS;printS;printI;printS;printS;printI;printP;printP;printI;end.

Notes:

  1. Some dialects of Pascal are not so strict about that: TheFPC has the option{$extendedSyntax on} which will allow the program above to compile anyway.
  2. Thelabel-section has intentionally been omitted.
  3. The Extended Pascal standard allows so-called “forward declarations” [remote directive]. A forward declaration of a routine is just the declaration, no definition.
  4. Some compilers support the generation of non-standardized “run-time type information” (RTTI). By enablingRTTI,type declarationsdo produce data thatis stored in your program.
  5. One such compiler optimization is calledinlining. This will effectively copy a routine definition to the call site.Pure functions even stand to benefit by being defined as isolated functions, provided the compiler does support appropriate optimizations.


Next Page: Enumerations | Previous Page: Expressions and Branches
Home: Pascal Programming
Retrieved from "https://en.wikibooks.org/w/index.php?title=Pascal_Programming/Routines&oldid=4092123"
Category:

[8]ページ先頭

©2009-2025 Movatter.jp