PurePascal-Kurs (4)

In den ersten drei Folgen des Kurses wurden die Grundlagen der Programmiersprache Pascal vermittelt. Ab dieser vierten Folge wird immer wieder auf Elemente der Grundlagen zurückgegriffen, weshalb Sie sich in jedem Fall mit dem Inhalt der ersten drei Folgen vertraut machen sollten. Die Teile 4 und 5 behandeln die Unterprogramme (Prozeduren und Funktionen), d.h. deren Verwendung.

6 Prozeduren und Funktionen

6.1 Prozeduren

Ein Programm soll einfach und übersichtlich sein. Die Wartbarkeit eines Softwareproduktes ist heute ein sehr wichtiges Kriterium. Bei der Entwicklung ist unbedingt darauf zu achten, dass übersichtliche Einheiten in Form von Unterprogrammen entstehen, die zusammen die Funktionalität des Gesamtsystems ergeben. Unterprogramme sind Prozeduren und Funktionen.

Es gibt mehrere Gründe, warum Prozeduren eingesetzt werden sollen und können:

  1. Auslagern sich wiederholender Programmteile
  2. Modularisierung von Programmen/Strukturieren
  3. Aufteilen in kleine Programmeinheiten
  4. Einsatz von Standardprozeduren

Allgemein kann man sagen, Prozeduren erzeugen aus einer Eingangsdatenmenge eine Ausgangsdatenmenge. Es lassen sich folgende Prozeduren unterscheiden:

  1. einfache, parameterlose Prozeduren
  2. Prozeduren mit Wertübergabe
  3. Prozeduren mit Variablenübergabe
  4. Prozeduren mit Mischparametern

Wie die Variablen sind die Prozeduren im Deklarationsteil aufzuführen. Prozeduren enthalten Variablen, Konstanten und Anweisungen - also eine einzeln testbare Einheit. Prozeduren können weitere Funktionen und Prozeduren enthalten. Prozeduren werden im Vereinbarungsteil mit

gekennzeichnet.

Prozeduren werden im Hauptprogramm (oder in einer anderen Prozedur) mit ihrem Namen und der Parameterliste aufgerufen.

6.1.1 Prozeduren ohne Parameterübergabe

Eine Prozedur kann allein mit ihrem Namen aufgerufen werden, wenn keine Daten für den Ablauf benötigt werden. Es können aber zu jeder Zeit globale Daten eingesetzt werden. Da in der objektorientierten Programmierung der Einsatz von globalen Daten nicht mehr vorgesehen ist, sollten ausschließlich lokale Daten eingesetzt werden.

Hier soll der Einsatz der Prozedur an einem einfachen Beispiel erläutert werden. Sind an zwei oder mehr Stellen im Programm gleichlautende Programmzeilen vorhanden, kann man sie als Prozedur auslagern. An den betreffenden Stellen erfolgt dann nur noch der Prozeduraufruf.

In dem vereinfachten Struktogramm (Abbildung 20: es fehlen hier einige Anweisungen, die im Programmcode stehen) wiederholen sich vor und in der Schleife zwei Zeilen (grau hinterlegt). Diese können, speziell, wenn es noch mehr Zeilen sind, ausgelagert werden. Die Auslagerung bedeutet eine wesentliche Vereinfachung. Die Anweisungen sind als Programmteil nur einmal im Speicher. Durch Aufruf des ausgelagerten Bereichs mit dem vereinbarten Namen - dem Prozeduraufruf - verzweigt das Programm zur Prozedur und nach deren Abarbeitung wieder in das Hauptprogramm. In dem obigen Struktogramm müssten dann die 2 jeweils grau hinterlegten Zeilen durch die folgende ersetzt werden.

Für die Prozedur "ZaehlerEingabe" erstellt man dann ein eigenes Struktogramm.

Der Programmcode für das komplette Beispielprogramm aus Abbildung 20 sieht dann wie folgt aus: (Listing 1).

Wie zu sehen ist, steht im Deklarationsteil nach der Vereinbarung der Variablen die Prozedur "ZaehlerEingabe". Sie wird wie ein "normales" Programm mit dem Namen, gefolgt von dem Schlüsselwort be-gin, eingeleitet und mit dem Schlüsselwort end beendet. Wichtig ist hierbei, dass hinter dem end kein Punkt, sondern ein Semikolon folgt! Dieser Prozedur können beliebig viele Prozeduren folgen. Im Programmteil wird die Prozedur dann einfach über deren Namen aufgerufen. Der restliche Teil des Programms, mit Ausnahme der Anweisung ClrEol, die die Zeile, in der der Cursor steht, von der Cursorposition bis zum Zeilenende löscht, sollte nach den ersten 3 Folgen dieses Kurses klar sein und wird deshalb nicht mehr erläutert.

6.1.2 Prozeduren mit Wertübergabe

Soll eine Prozedur mit unterschiedlichen Werten aufgerufen werden, kann eine "Prozedur mit Wertübergabe" eingesetzt

program Wasserverbrauch;
uses  crt;
var ZaehlerAlt, ZaehlerNeu, Verbrauch, SummeVerbr: real;
procedure ZaehlerEingabe;
begin
GotoXY(35, 6); ClrEol; readln(ZaehlerAlt) GotoXY(35, 8); ClrEol; readln(ZaehlerNeu)
end;
begin
ClrScr;
GotoXY(5, 3); 
write('Summe des Wasserverbrauchs'); GotoXY(5, 6); 
write(,Alter Zahlerstand (Ende=0): ,); 
GotoXY(5, 8); write(,Neuer Zahlerstand (Ende=0): ,); 
GotoXY(5,12); write(,Verbrauch: ... ,); 
GotoXY(5,14); write(,Summe Verbrauch: ... ,); 
SummeVerbr := 0;
ZaehlerEingabe;                         { Prozedur-Aufruf }
while (ZaehlerNeu <> 0) and (ZaehlerAlt <> 0) do begin
if ZaehlerNeu < ZaehlerAlt then
ZaehlerNeu := ZaehlerNeu + 100000; 
Verbrauch := ZaehlerNeu - ZaehlerAlt; 
SummeVerbr := SummeVerbr + Verbrauch; 
GotoXY(17, 12); 
write(Verbrauch :8 :0); 
GotoXY(23, 14); write(SummeVerbr :8 :0); 
ZaehlerEingabe    ( Prozedur-Aufruf ) end;
GotoXY(60, 22); write(,Ende des Programms'); end.

werden. Der Ablauf, die Tätigkeit der Prozedur, richtet sich nach diesen übergebenen Werten. Unterschiedliche Werte können unterschiedliche Arbeitsweisen ergeben. Mit jedem Aufruf wird der aktuelle Wert an die Prozedur übergeben.

Der Aufruf erfolgt nach folgendem Schema:

Prozedurname (Parameterliste);

In der Parameterliste werden die Variablen mit ihrem Datentypen vereinbart. Bei mehreren Variablen gleichen Datentyps werden diese durch ein Komma getrennt vor dem Doppelpunkt aufgelistet. Variablen verschiedenen Datentyps werden nach der Nennung des Datentyps durch ein Semikolon getrennt. In dem folgenden Beispiel sollen in einem Ausgabeprogramm Leerzeilen eingefügt werden. Je nach Druckposition sind mehr oder weniger Leerzeilen vorzusehen (Listing 2).

Kurze Wiederholung:

Für den Einsatz einer Prozedur sind nötig:

  1. Vereinbarung: procedure Prozedurname

(Liste der formalen Parameter); Vereinbarung von Variablen begin

end;

  1. Aufruf

Prozedurname (Liste der aktuellen Parameter);

Wichtig: Die formalen und aktuellen Parameter müssen hinsichtlich Datentyp und Anzahl der Elemente übereinstimmen Aufbau der Prozedur mit Wertübergabe:

program NAME; uses ... var...

procedure Prozedurname(Variablenname: Datentyp);

var Lokalevariable: Datentyp;

begin

end; begin

Prozedurname(aktuellerParameter);

end.

(Beispiel siehe Listing 3).

Zulässige Datentypen:

Die Datentypen der Prozedurvereinbarung dürfen nur aus einem einfachen Wort bestehen:

Nicht zulässig ist z.B. string[40]! Als Abhilfe hierzu kann man hinter der Befehls-

program Ausgabe;  
uses crt;  
procedure LEER(Anzahl: integer); {Die Prozedur übernimmt  
var Lauf: integer; {einen Parameter, begin  
for Lauf := 1 to Anzahl do {der als Laufgrenze einge-  
writeln; {setzt wird. end;  
begin  
ClrScr;  
writeln(,Es folgt 1 Leerzeile'); LEER(1); (Aufruf mit Anzahl = 1 }  
writeln(,Es folgen 4 Leerzeilen'); LEER(4); {Aufruf mit Anzahl = 4 }  
writeln(,Es folgen 2 Leerzeilen');

LEER(2); (Aufruf mit Anzahl = 2 }

writeln('Das genügt!'); end.

procedure BEISPIELl(H, L, K: integer); begin  
end; begin  


BEISPIELl(trunc(Netto * MWST), 3, 24); end.  
procedure BEISPIEL2(A, B, C: integer; D, E: char; Y, Z: real);  
begin  
end; begin  
BEISPIEL2(2, 6, 4, ,a', ,b', 123.12, 0.14);  
end.
  1. Aufruf im Anweisungsteil:

Prozedurname(Variable A, Variable B); Prozedurname(Zahl_l, Zahl_2);

Beispiel 1 - Vereinbarungen:

procedure PRODOKT(var A, B, C: integer);
procedure FORMEL(var A, B, C: integer; var X, Y: real);

Beispiel 2 - Programm:

program VERBRAUCH;
uses crt;
type string20=string[20];
var VERBRAUCH, ALTWERT, NEUWERT : longint;
procedure EINGABE(var Wert: longint; HINWEIS: string20);
begin
write(HINWEIS) {der als Laufgrenze einge- }
readln(WERT) {setzt wird. }
end;
begin
ClrScr;
writeln('Bestimmung des Verbrauchs');
writeln('Werte bitte ganzzahlig eingeben!');
EINGABE(NEDWERT, ,abgelesenerWert: ,); {Aufruf }
EINGABE(ALTWERT, ,letzterWert: ,); {Aufruf }
VERBRAUCH := NEUWERT - ALTWERT;
writeln('Der Verbrauch betragt: ', VERBRAUCH); end.
zeile uses ... eine TYPE-Vereinbarung treffen, mit der man einen neuen Datentypen definiert:

uses...

type Text = string[40];

procedure ADRESSE(Name, Vorname: text);

6.1.3 Prozeduren mit Variablenübergabe

Wird das Ergebnis einer Prozedur unterschiedlichen Variablen zugewiesen, kann die "Prozedur mit Variablenübergabe" eingesetzt werden.

Eine vorhandene Prozedur kann nun einfach mit unterschiedlichen Variablennamen aufgerufen werden.

Allgemeine Form:

  1. Deklaration im Vereinbarungsteil:

procedure Prozedurname(var Variable1, Variable2: Datentyp); var... begin

end;

Das Schlüsselwort var in der Parameterliste sorgt dafür, dass nur die Adresse, an der der Inhalt der Variablen abgelegt ist, übergeben wird und nicht der Inhalt der Variablen.

Hieraus folgt, dass wenn der Variablen (z.B. Variablei) während des Prozedurablaufes ein Wert zugewiesen wird, dieser auch nach dem Verlassen der Prozedur in der Variablen steht.

In den Struktogrammen (Abbildungen 23 und 24) zum Programm in Beispiel 2 zeigen sich die Grenzen der Darstellung. Die Übergabe von Werten oder Variablen an eine Prozedur wird separat z.B. im Team vereinbart.

In der nächsten Folge dieser Reihe folgen dann die Funktionen, die im Gegensatz zu den Prozeduren auch direkt einen Wert zurückgeben können.


Torsten Runge
Aus: ST-Computer 07 / 1999, Seite 36

Links

Copyright-Bestimmungen: siehe Über diese Seite