Imperative Programmierung

Imperative Programmierung (lateinisch imperare ‚anordnen‘, ‚befehlen‘) ist ein Programmierparadigma, nach dem „ein Programm aus einer Folge von Anweisungen besteht, die vorgeben, in welcher Reihenfolge was vom Computer getan werden soll“.[1]

Die imperative Programmierung ist das am längsten bekannte Programmierparadigma. Bedingt durch den Sprachumfang früherer Programmiersprachen war diese Vorgehensweise ehemals die klassische Art des Programmierens. Sie liegt dem Entwurf vieler Programmiersprachen, zum Beispiel ALGOL, BASIC, Fortran, Pascal, Ada, PL/I, Cobol, C und allen Assemblersprachen zugrunde.[1]

Abweichende Bezeichnungen: In der Literatur wird dieses Entwicklungskonzept zum Teil auch „imperativ/prozedural“, „algorithmisch“[2] oder auch „zustandsorientiert“[3] genannt. Auch die Bezeichnung „prozedurale Programmierung“ wird zum Teil synonym verwendet, was jedoch abweichend auch mit „Verwendung von Prozeduren“ definiert wird.

Details

Bestimmende Merkmale für diese Art des Programmierens sind:[4][5]

  • Im Quellcode wird festgelegt, was in welcher Reihenfolge und wie zu tun ist: „First do this and next do that“[4], schrittweises ‚Fortschreiten‘ der Befehle; „viewed as sequence of things to be done“[5] (dargestellt als Folge von Anweisungen).
  • Zur Steuerung der Befehlsausführung verwendet der Entwickler Kontrollstrukturen, z. B. Sequenz, Schleife, bedingte Verzweigung.

Das dem imperativen Paradigma zugrunde liegende abstrakte Ausführungsmodell ist eng angelehnt an die Ausführung von Maschinencode auf Computern, die nach der Von-Neumann-Architektur implementiert sind. Es existieren beispielsweise bedingte und unbedingte Sprunganweisungen. Der Status des Rechners bzw. des Programms ergibt sich aus dem Inhalt von Datenfeldern im Arbeitsspeicher und dem Zustand von Systemvariablen (z. B. Register, Befehlszähler …).

Die Hardware-Implementierung fast aller Computer ist imperativ. Nahezu die gesamte Computerhardware ist für die Ausführung von Maschinensprache ausgelegt, die dem Computer eigen ist und im imperativen Stil geschrieben ist. Aus dieser einfachen Perspektive wird der Programmstatus durch den Inhalt des Speichers definiert, und die Anweisungen sind Anweisungen in der nativen Programmiersprache des Computers. Übergeordnete imperative Sprachen verwenden Variablen und komplexere Aussagen, folgen jedoch immer noch demselben Paradigma. Rezepte und Prozess-Checklisten sind zwar keine Computerprogramme, aber auch bekannte Konzepte, deren Stil der imperativen Programmierung ähnelt. Jeder Schritt ist eine Anweisung, und die physische Welt hält den Zustand. Da die Grundideen der imperativen Programmierung sowohl konzeptionell vertraut als auch direkt in der Hardware enthalten sind, sind die meisten Computersprachen im imperativen Stil.

Zuweisungen führen im imperativen Paradigma eine Operation für Informationen im Speicher durch und speichern die Ergebnisse zur späteren Verwendung im Speicher. Höhere imperative Sprachen ermöglichen darüber hinaus die Auswertung komplexer Ausdrücke, die aus einer Kombination von arithmetischen Operationen und Funktionsauswertungen bestehen können, sowie die Zuordnung des resultierenden Werts zum Speicher. Durch Schleifenanweisungen (while-Schleifen, do-while-Schleifen und for-Schleifen) kann eine Folge von Anweisungen mehrmals ausgeführt werden. Schleifen können entweder die Anweisungen ausführen, die sie vordefiniert enthalten, oder sie können sie wiederholt ausführen, bis sich einige Bedingungen ändern. Bedingte Verzweigungsanweisungen ermöglichen die Ausführung einer Folge von Anweisungen nur, wenn eine Bedingung erfüllt ist. Andernfalls werden die Anweisungen übersprungen und die Ausführungssequenz wird ab der darauf folgenden Anweisung fortgesetzt. Unbedingte Verzweigungsanweisungen ermöglichen die Übertragung einer Ausführungssequenz auf einen anderen Teil eines Programms. Dazu gehören die Sprunganweisung, switch und das Unterprogramm, die Unterroutine oder der Prozeduraufruf, der normalerweise nach dem Aufruf zur nächsten Anweisung zurückkehrt.

Zu Beginn der Entwicklung höherer Programmiersprachen ermöglichte die Einführung des Blocks die Erstellung von Programmen, in denen eine Gruppe von Anweisungen und Deklarationen so behandelt werden konnte, als wären sie eine Anweisung. Dies ermöglichte neben der Einführung von Unterprogrammen, komplexe Strukturen durch hierarchische Zerlegung in einfachere prozedurale Strukturen auszudrücken.

Viele imperative Programmiersprachen sind Abstraktionen der Assemblersprache.[6]

Abgrenzung

Als Gegenentwurf zur imperativen Programmierung gilt das Paradigma der deklarativen Programmierung. Bei der deklarativen Programmierung wird vom Entwickler im Quellcode definiert, was das Programm machen soll, aber nicht wie.

„Die meisten […] Programmiersprachen, darunter auch objektorientierte Sprachen wie C#, Visual Basic .NET, C++ und Java, unterstützen in erster Linie [auch] die imperative […] Programmierung“.[2] Das Prinzip der Datenkapselung (information hiding) wird in imperativen Sprachen oft dadurch umgesetzt, dass Prozeduren, die eine logische Einheit bilden, in Modulen oder Paketen zusammengefasst werden.

Nicht maßgeblich für die Einstufung als ‚imperativ‘ ist die Tatsache, dass bei der physischen Ausführung von Computerprogrammen im Prozessor die einzelnen Befehle des Maschinencodes „Befehl für Befehl“ ausgeführt werden, denn dies ist unabhängig vom praktizierten Paradigma immer so. Vielmehr setzt ‚imperativ‘ voraus, dass „ein Entwickler Code erstellt, der detailliert die Schritte beschreibt, die der Computer zur Erfüllung der Aufgabe ausführen muss“.[2] Deklarativ erstellte Anweisungen etwa werden von übergeordneten oder eingebundenen Systemkomponenten – und nur ‚basierend‘ auf dem Quellcode – in ausführbare Maschinenbefehle umgeformt. Beispiel ‚SQL-Kommandos‘: Komponenten der Systemsoftware des Datenbankmanagementsystems interpretieren sie, erzeugen daraus Maschinencode und lassen diesen ausführen.

Beispiel

Ausgabe der Quadratzahlen ungerader Zahlen von 3 bis 11.

Imperative Programmierung (Beispiel in der Programmiersprache C):

for (int i = 3; i < 12; i += 2)
{
    printf("%d\n", i * i);
}

Funktionale Programmierung (Beispiel in der Programmiersprache Haskell):

mapM_ print [ i^2 | i <- [3,5..11] ]

Literatur

  • Terrence W. Pratt, Marvin V. Zelkowitz: Programming Languages: Design and Implementation. 4. Auflage. Prentice Hall, 2000, ISBN 978-0-13-027678-0.
  • Robert W. Sebesta: Concepts of Programming Languages. 9. Auflage. Addison-Wesley, 2009, ISBN 978-0-13-607347-5.

Einzelnachweise

  1. a b Böhm, Jungkunz: Grundkurs IT-Berufe. Vieweg-Verlag, books.google.de
  2. a b c Microsoft Library MSDN
  3. Goos: Vorlesungen über Informatik. books.google.co.uk
  4. a b Java and Object-Oriented Programming Paradigm. books.google.com
  5. a b Programming Paradigms and Methodology. books.google.com
  6. Bruce Eckel: Thinking in Java. Pearson Education, 2006, ISBN 978-0-13-187248-6, S. 24 (google.com).