Unterprogramm

aus Wikipedia, der freien Enzyklopädie
Wechseln zu: Navigation, Suche
Grundprinzip eines Unterprogramms

Ein Unterprogramm ist ein Teil eines Computerprogramms, das eine bestimmte Funktionalität bereitstellt. Es kann von anderen Programmen/Programmteilen aufgerufen werden, um eine Aufgabe zu übernehmen und verzweigt danach wieder an die aufrufende Stelle zurück. Ein Unterprogramm wird i. d. R. durch einen Bezeichner (z. B. einen Namen) identifiziert, und ihm können zur Verarbeitung Daten als Argumente übergeben werden.[1]

Bezüglich der Terminologie kennt man aus der Praxis einen großen Reichtum an Varianten, die teilweise synonym, teilweise mit semantischen Unterschieden angewendet werden.[1] Bezeichnungen wie Prozedur (procedure), Funktion (function), Routine oder Subroutine, Operation, Section, Modul sind teils historisch und oft im Umfeld verschiedener Programmiersprachen entstanden, entsprechen aber im Wesentlichen der Bedeutung ‚Unterprogramm‘ oder werden so genannt. So sind im Kontext der objektorientierten Programmierung Methoden (methods) – je nach Programmiersprache – einer Klasse, einem Objekt oder einer generischen Funktion als in sich abgeschlossene Einheiten zugeordnet.

Bezüglich der Erstellung, Wartung und Ausführung können Unterprogramme je nach Art der Implementierung eigenständige Komponenten sein (‚Unterprogramme‘ im engeren Sinn, die oft vorübersetzt in Programmbibliotheken zusammengefasst sind) oder zusammen mit anderen Funktionsteilen den Programmcode eines (1) Programms bilden.

Zweck von Unterprogrammen[Bearbeiten]

Das Kapseln von Programmteilen in Unterprogrammen entspringt dem Paradigma der prozeduralen Programmierung. Die beiden wichtigsten Vorteile, die dadurch beim Softwaredesign erzielt werden, sind die Wiederverwendbarkeit von Programmteilen und die Verbesserung der Verständlichkeit und Wartbarkeit des Quelltexts.

Unterprogramme für bestimmte technische oder betriebliche Funktionen (z. B. eine Prüfziffernberechnung) als unternehmensweiter Standard sind ein Aspekt der Softwarearchitektur.

Eine Weiterführung des Konzepts der Unterprogramme sind die modulare Programmierung und Software-Module.

Terminologie[Bearbeiten]

Funktion
In Programmiersprachen wie C, C++, C#, Java oder Python werden alle Unterprogramme grundsätzlich Funktion genannt. In Sprachen wie Pascal oder BASIC werden nur diejenigen Unterprogramme als Funktion bezeichnet, die einen Wert an den Aufrufer zurückliefern.
Prozedur
Oft wird unter Prozedur eine spezielle Funktion verstanden, die keinen Rückgabewert liefert (z. B. in Pascal oder BASIC ). FORTRAN77 fasst unter procedures alle Funktionen und prozedurale Unterprogramme (subroutines) zusammen.[2]
Abweichend davon werden in COBOL als Prozeduren lediglich die in der ‚Procedure Division‘ formulierten, durch ‚Paragraphen‘ benennbaren Anweisungen (Befehle) bezeichnet, unabhängig davon, ob sie als Unterroutine verwendet werden oder nicht. Auch in PL/I bezeichnet man die im Befehlsteil des Quelltextes enthaltenen – prozedural (= ‚fortschreitend‘) zu verarbeitenden – Anweisungen als „Prozeduren“.
Methode
Unter einer Methode versteht man in objektorientierten Programmiersprachen Unterprogramme von bzw. in Klassen.

Geschichte[Bearbeiten]

David Wheeler, Maurice V. Wilkes und Stanley Gill gelten als Entwickler der ersten Subroutine (damals auch Wheeler-jump genannt).[3][4][5][6]

In frühen imperativen Programmiersprachen (zum Beispiel frühe BASIC- und FORTRAN-Varianten) gab es nur das Konzept des parameterlosen Unterprogramms, welches über Sprunganweisungen aufgerufen wurde und ausschließlich über globale Variablen mit dem Hauptprogramm wechselwirken konnte.

Mit dem Aufkommen der strukturierten Programmierung entwickelte sich das Konzept der Prozedur mit Aufrufparametern, die zunächst überwiegend als Referenzparameter übergeben wurden (call-by-reference), das heißt eine Änderung des Parameters innerhalb der Prozedur ändert den zugehörigen Parameter an der Aufrufstelle der Prozedur. Die Einführung von expliziten Rückgabewerten von Prozeduren (respektive Funktionen) ermöglichte die Berechnung von Resultaten, ohne die Referenzparameter zu verändern.

In einem weiteren Schritt wurden Wertparameter zur Übergabe an Prozeduren eingeführt (call-by-value), um unerwünschte Rückwirkungen auf das Hauptprogramm weiter zu reduzieren.

Zur Vermeidung von Programmfehlern wurde in einigen Programmiersprachen wie zum Beispiel Pascal eine starke Typisierung von Parametern eingeführt: die tatsächlich verwendeten Parameter müssen hierbei relativ streng zuweisungskompatibel mit den formal deklarierten Parametern sein.

In manchen Programmiersprachen, wie beispielsweise Modula-2, können Prozedurvariablen aufgerufen oder als Parameter eingesetzt werden.

Schließlich wurden Prozeduren als objektbezogene Methoden oder Zugriffsfunktionen Bestandteil des objektorientierten Paradigmas, etwa in den Programmiersprachen Java und C++.

Unterschiedliche Implementierungen[Bearbeiten]

Unterprogramme können, abhängig von der verwendeten Entwicklungsumgebung oder Programmiersprache, unterschiedlich implementiert sein:

  • Als logisch in sich geschlossener Teil im Quelltext eines Programms. Hinsichtlich der administrativen Verwaltung (z. B. bei Änderungen), der Kompilierung und der technischen Ausführung auf einem Computer gehören solche Quelltextabschnitte fest zum Gesamtprogramm. Je nach Programmiersprache (z. B. bei Cobol) und Programmierstil hat die Subroutine Zugriff auf alle, nur bestimmte oder nur ihre eigenen Daten und Funktionen.
Eine Variante sind Programmcodeteile, die als eigenständige, in Programmbibliotheken verwaltete Quelltext-Elemente geführt werden: Diese werden im Quelltext der sie benutzenden Programme durch spezielle Anweisungen (z. B. Include) aufgerufen und in dem zur Kompilierung (temporär) bereitgestellten Quellcode eingefügt. Solche Codeteile aus Quelltextbibliotheken werden (z. B. bei COBOL oder RPG[7]) copybook genannt.
  • Als administrativ und zur Ausführung eigenständige Programme. Sie werden erst zur Ausführungszeit „dynamisch“ geladen. Zum Teil, zum Beispiel bei DLL's, können solche ‚nachgeladenen Module‘ mehrere und unterschiedliche Unterprogramme enthalten. Details siehe Dynamisches Linken.
  • Eine Mischform aus beidem sind Unterprogramme mit ebenfalls eigenständigem Quelltext und getrennter Kompilierung. Ihr Maschinencode wird jedoch zusammen mit dem Code sie aufrufender Programme zu einer ausführbaren Datei „statisch gebunden“. Details siehe Statisches Linken.

Innerhalb dieser Grundvarianten stellen bestimmte Programmiersprachen weitere Funktionsdetails bereit, die beim Binden und Laden von Unterprogrammen anwendbar sind. Siehe dazu die Beispiele zu Überladen oder Überschreiben.

Eine besondere Kategorie von Unterprogrammen bilden die in einem Computersystem bereitgestellten Systemfunktionen (wie Lesen, Schreiben, Clock usw.). Sie werden im engeren Sinn nicht als Unterprogramm bezeichnet, jedoch nach demselben Ablaufprinzip benutzt: Aufruf mittels Anweisung, meist mit Parameter-/Argumentenübergabe, Ausführung der Subfunktion zum Beispiel im Betriebssystem, anschließend Rückkehr ins rufende Programm mit Fortsetzung der Verarbeitung.

Beispiele[Bearbeiten]

Die Beispiele in den Programmiersprachen C, C++ und Java zeigen Details zur Programmierung mit Unterprogrammen.

C, C++ oder Java[Bearbeiten]

Das folgende Beispiel ist ein in Unterprogramm in C, C++ oder Java, das beim Aufruf einen Wert entgegennimmt und ihn mit einem konstanten Wert multipliziert, es soll die Umrechnung von Zoll in Zentimeter demonstrieren.

float inch2cm(float l)
{
    return 2.54 * l;
}

Python[Bearbeiten]

Das folgende Beispiel in Python gibt die in txt übergeben Zeichenkette auf dem Bildschirm aus, liefert aber keinen Wert zurück.

def hello(txt):
    print txt

Assembler[Bearbeiten]

Ein einfaches Hallo-Welt-Programm in Assemblersprache, die vier Zeilen ab der Marke print stellen das Unterprogramm dar.

segment code
 
..start:
         mov ax, data
         mov ds, ax
         call print     ; Aufruf des Unterprogramms
         mov ah, 4Ch
         int 21h        ; Beenden des Programms
 
print:   mov dx, hello
         mov ah, 09h
         int 21h
         ret
 
segment data
  hello: db 'Hello World!', 13, 10, '$'

Beispiel Objektmodule Großrechner IBM-Welt[Bearbeiten]

  • Aufrufende Programme setzen einen Call-Befehl ab und übergeben dabei (mit ‚USING x, y ...‘) eine Liste mit den Adressen der Datenfelder/Datenstrukturen, die das Unterprogramm benötigt oder zurückgeben soll. Im Maschinencode des Programms wird dabei vom Compiler das Register 1 mit der Adresse der Adressliste und das Register 14 mit der Rücksprungadresse, Register 15 mit der Einsprungadresse im Unterprogramm geladen, danach wird (über ‚BR 15‘) dorthin verzweigt.
  • Aufgerufene Programme übernehmen die übergebenen Adressen zur Adressierung ihrer strukturidentischen Datendeklarationen (deren Bezeichner jedoch anders gewählt werden können), wodurch diese 'fremden' Daten mit den Befehlen des Unterprogramms ansprechbar sind.
  • Nach der Verarbeitung im Unterprogramm erfolgt der Rücksprung über das Register 14. Weitere Details siehe Artikel Modul, Abschnitt Beispiele.

Parameter/Argumente[Bearbeiten]

Hauptartikel: Parameter (Informatik)

Unterprogramme (UP) führen Funktionen aus, die in der Regel Daten benötigen, die zu den sie aufrufenden Programmen gehören. Aus Sicht des Unterprogramms können diese Daten Eingangs- oder Ergebniswerte sein. Da je nach angewendeter Unterprogrammtechnik ein Unterprogramm grundsätzlich nur ‚Zugriff‘ auf seine eigenen Daten hat, enthalten die Programmiertechniken und -Sprachen Mechanismen, mit denen die 'fremden' Daten für das Unterprogramm verfügbar gemacht werden; nur dann können dessen Befehle die für sie ‚externen‘ Daten ansprechen. Je nach UP-Variante/Programmiersprache können diesbezüglich verschiedene Konstellationen unterschieden werden:

  • Das Unterprogramm kann auf alle im Hauptprogramm definierten Daten zugreifen. Meist ist das nur bei Unterroutinen der Fall, die zum Quellcode des Hauptprogramms gehören.
  • Das Unterprogramm kann auf Daten(bereiche) zugreifen, die als ‚global‘ deklariert wurden.
  • Der Unterroutine werden 'ihre' Daten beim Aufruf explizit ‚mitgeteilt‘. Die Angaben dazu sind sogenannte „Parameter“.

Die Parametertechnik wird vor allem bei unabhängig vom aufrufenden Programm entwickelten Unterprogrammen verwendet, um einem aufzurufenden UP mitzuteilen, welche Daten es verwenden/verarbeiten soll. Diese Parameter bilden die gemeinsame Schnittstelle zwischen aufrufendem und aufzurufendem UP. Ein Beispiel ist "DispoSaldoPrüfen (Kontonummer, Betrag, Antwort)". Im Unter- und im Hauptprogramm sind diese Angaben nach einheitlich angewendeten Konventionen strukturell identisch zu deklarieren. Die während der Programmausführung beim einzelnen Aufruf tatsächlich übergebenen Werte werden 'Argumente' genannt, z.B. als Kontonummer der Wert '4711' und als Betrag '-500,00', als Antwort könnte alternativ 'OK' oder 'Überziehung' zurückgeliefert werden. Dieses Begriffspaar (Parameter und Argument) wird synonym auch als formale und tatsächliche Parameter bezeichnet.

Parameter/Argumente können elementare Datenfelder beliebigen Formats sein, z. B. Text oder Integer – oder auf beiden Seiten der Schnittstelle einheitlich definierte Datenstrukturen. Bezüglich der Verwendbarkeit der übergebene Daten kann unterschieden werden, ob diese nur gelesen oder auch verändert werden können, zum Beispiel für Ergebniswerte. Weiterhin lässt sich unterscheiden, ob mit den Parametern Adressen (im Hauptspeicher) oder die tatsächlichen Daten übergeben werden.

Technisch (z. B. im Maschinencode) erfolgt die Übergabe der Parameter/Argumente je nach verwendeter Programmiersprache und Rechnertechnologie mithilfe unterschiedlicher Hardware-Einrichtungen. So kann z. B. der Stack die Argumente aufnehmen oder Parameter werden über Register übergeben.

Einzelnachweise[Bearbeiten]

  1. a b FU Berlin Unterprogramme [1]
  2. FORTRAN77-Standard, Kap. 15. Abgerufen am 20. September 2010 (englisch).
  3. David Wheeler. 1985 Computer Pioneer Award. In: www.computer.org. IEEE, abgerufen am 20. Oktober 2013.
  4. David Wheeler. 2003 Fellow. In: computerhistory.org. Computer History Museum, abgerufen am 20. Oktober 2013.
  5.  David J. Wheeler: The use of sub-routines in programmes. In: Proceedings of the 1952 ACM national meeting (Pittsburgh). ACM, New York 1952, S. 235–236, doi:10.1145/609784.609816.
  6.  Maurice V. Wilkes, David J. Wheeler, Stanley Gill: Preparation of Programs for an Electronic Digital Computer, with special reference to the EDSAC and the use of a library of subroutines. 1. Auflage. Addison-Wesley, Cambridge (Massachusetts) 1951, S. 22, OCLC 1189900 (Online, abgerufen am 20. Oktober 2013).
  7. Niraj: AS400 Copybooks | RPGLE Copybooks | ILE RPG Copybooks. In: Let's AS400. 30. Juli 2012, abgerufen am 3. November 2013.