Vorlesung „Programmieren“

Werbung
Vorlesung „Programmieren“
Programmierparadigmen
Prof. Dr. Stefan Fischer
Institut für Telematik, Universität zu Lübeck
http://www.itm.uni-luebeck.de/people/fischer
Programmiersprachen-Paradigmen
• Eine Programmiersprache dient dem
Aufschreiben von Algorithmen
– Ein Compiler übersetzt in Maschinensprache
• Die Art und Weise des „Aufschreibens“
unterscheidet sich je nach
Programmiersprache sehr deutlich
– Verschiedene Paradigmen existieren
– Bisher: Imperative Programmierung
Security - 04 Cryptology
#2
Unterschiedliche Sprachenkonzepte
•
Imperative Programmiersprachen
– Grundprinzip: Folge von Variablenzuweisungen
– Wesentlich: Prozedurale Programmierung
– Beispiele: Algol, Fortran, Cobol, Pascal, C, Basic
– Spezialfall: Objektorientierte Programmierung
• Grundprinzip: Interaktionen zwischen „Objekten“
• Beispiele: SmallTalk, Java, C++
•
Funktionale Programmiersprachen
– Grundprinzip: Term-Ersetzung
– Beispiele: Lisp, HOPE, Miranda, SML, Haskell
•
Logikbasierte Programmiersprachen
– Grundprinzip: Prädikatenlogik
– Beispiel: Prolog
5-3
Motivation
Security - 04 Cryptology
#4
Beispiel: Mehrmals Leerzeichen zählen
• Aufgabe: Zähle Leerzeichen in beiden
folgenden Sätzen und gebe beides aus
– „Man muss die Welt nicht verstehen, man muss
sich nur darin zurechtfinden. (Albert Einstein)“
– „Die besten Dinge im Leben sind nicht die, die man
für Geld bekommt.(Albert Einstein)“
Security - 04 Cryptology
#5
Mögliches Programm
public class Zeichenzaehlen {
public static void main(String[] args){
char text[] = "Man muss […] darin zurechtfinden. (Albert Einstein)".toCharArray();
int anzahlLeerzeichen = 0;
for(int aktuellesZeichen = 0; aktuellesZeichen < text.length; aktuellesZeichen++) {
if( text[aktuellesZeichen] == ' ' ) {
anzahlLeerzeichen++;
}
}
System.out.print(anzahlLeerzeichen);
char text2[] = "Die besten Dinge […] Geld bekommt. (Albert Einstein)".toCharArray();
int anzahlLeerzeichen2 = 0;
for(int aktuellesZeichen2 = 0; aktuellesZeichen2 < text2.length; aktuellesZeichen2++) {
if( text2[aktuellesZeichen2] == ' ' ) {
anzahlLeerzeichen2++;
}
}
System.out.print(anzahlLeerzeichen2);
}
}
Bildquelle: http://www.konsumer.info/?p=15528, Programm: 08-Programmierparadigmen\1-Zeichenzaehlen\Zeichenzaehlen.java
Security - 04 Cryptology
#6
Ausgabe des Programms
• 2 x 13 Leerzeichen?
• Kann das stimmen?
• Zufällig gleich viele?
• Haben wir einen Fehler
gemacht beim Anpassen
des Programms?
Security - 04 Cryptology
#7
Beliebter Fehler
public class Zeichenzaehlen {
public static void main(String[] args){
char text[] = "Man muss […] darin zurechtfinden. (Albert Einstein)".toCharArray();
int anzahlLeerzeichen = 0;
for(int aktuellesZeichen = 0; aktuellesZeichen < text.length; aktuellesZeichen++) {
if( text[aktuellesZeichen] == ' ' ) {
anzahlLeerzeichen++;
}
}
System.out.print(anzahlLeerzeichen);
char text2[] = "Die besten Dinge […] Geld bekommt. (Albert Einstein)".toCharArray();
int anzahlLeerzeichen2 = 0;
}
for(int aktuellesZeichen2 = 0; aktuellesZeichen2 < text2.length; aktuellesZeichen2++) {
if( text[aktuellesZeichen2] == ' ' ) {
anzahlLeerzeichen2++;
}
}
System.out.print(anzahlLeerzeichen);
Copy/Paste-Fehler
}
Bildquelle: http://www.konsumer.info/?p=15528, Programm: 08-Programmierparadigmen\1-Zeichenzaehlen\Zeichenzaehlen.java
Security - 04 Cryptology
#8
Motivation
• Bisher möglich: Lange
Abfolge von Code
• Probleme
–
–
–
–
–
Lesbarkeit
Fehleranfälligkeit
Viel Copy & Paste
Keine zentrale Fehlerbehebung
Große Programme nicht
wartbar
Betriebssystem
Codezeilen
Windows NT 3.1
4-5 Mio.
Windows NT 4.0
11-12 Mio.
Windows 2000
>29 Mio.
Windows XP
45 Mio.
Windows Server 2003
50 Mio.
OpenSolaris
9.7 Mio.
FreeBSD
8.8 Mio.
Mac OS X 10.4
86 Mio.
Linux Kernel 2.6.0
5.2 Mio.
Linux Kernel 2.6.35
13.5 Mio.
#9
Prozedurale Programmierung
Prozedurale Programmierung
•
Zerlegung von Programmen in kleinere,
wiederverwendbare Einheiten
– sog. Prozeduren
Monolithisches
Programm
• Vorteile
– Kapselung einzelner Funktionalitäten
– Bessere Wiederverwendbarkeit
– Lesbarerer Code
•
„Was tut er?“ (z.B. Zeichen zählen) statt „Wie tut er es?“ (die
ganzen Instruktionen)
– Fehlerbehebung an einer Stelle
#11
Prozedur (auch: Funktion)
• Eingabeparameter
– Übergabe von Werten an die Funktion
– Definiert als Menge von Variablen mit bestimmtem Datentyp
• Rückgabe
Eingabewerte
Prozedur /
Funktion
(Black Box)
– Wert mit einem bestimmten Datentyp
– Spezieller Datentyp für keine Rückgabe: void
• Beispiele für Deklarationen (sog. Signatur)
–
–
–
–
–
Ausgabewert
void main(String[] args);
int zaehleLeerzeichen(char[] text);
char[] rueckwaerts(char[] text);
boolean istLeerzeichen(char zeichen);
boolean istKontoGedeckt(int konto, int blz);
#12
Signatur und Implementierung
Signatur
(auch: Deklaration)
int zaehleLeerzeichen(char[] text)
{
// Hier steht die Implementierung der Funktion
// (in einer Blockanweisung)
}
Implementierung
(auch: Body oder Definition)
#13
Signatur und Implementierung
int zaehleLeerzeichen(char[] text)
{
int anzahlLeerzeichen = 0;
for(int i = 0; i < text.length; ++i)
if ( text[i] == ' ' )
anzahlLeerzeichen++;
return anzahlLeerzeichen;
}
Rückgabe der Funktion
(wichtig: Datentyp)
#14
Exkurs: Blockanweisung
• Blockanweisungen definieren einen eigenen
„Scope“ (Bereich)
• Beispiele
– „class MeinProgramm“
– Prozedur „main“
Security - 04 Cryptology
#15
Exkurs: Blockanweisung
• Begrenzen „Sichtbarkeit“
bzw. „Lebensdauer“ von
Elementen (z.B. Variablen)
• Beispiele
– Variable i (Zeile 3) „gehört“ zur
Klasse „Blockanweisung“
(globale Variable)
– Variable i (Z. 6) gehört zu
„main“ (lokale Variable)
– Variable i2 „lebt“ nur innerhalb
der Blockanweisung (Z. 9-11)
– Variable i3 von Z. 15-22
– Variable i4 in Z. 19
Security - 04 Cryptology
#16
Implementierung einer Funktion
• Wie eine „Erweiterung“ der
Blockanweisung
– Es gibt ein paar weitere
„lokale“ Variablen
– Stellen die Parameter einer
Funktion dar
• Parameter werden wie
normale lokale Variablen
verwendet werden
– Werte der Parameter werden
beim Aufruf festgelegt
Security - 04 Cryptology
#17
Aufruf von Funktionen
• Aufruf über
Namen
(Identifier)
der Funktion
• Übergabe
von
Parametern
an die
Funktion
– Richtige
Anzahl
– Richtiger
Datentyp
Security - 04 Cryptology
#18
Ausgabe des Programms
• Programm verhält sich identisch zu dem Copy & Paste-Programm
– Es unterscheidet sich daher nicht im Ergebnis
• Aber das Programm ist
–
–
–
–
lesbarer,
einfacher,
wartbarer,
wiederverwendbarer, ...
Security - 04 Cryptology
#19
Weiteres Beispiel: Inverter
Security - 04 Cryptology
#20
Mit Prozeduren
• Zerlegen in
einzelne
Operationen
– Zeichen lesen
– Auf „Enter“
prüfen
– Prüfen, ob noch
Platz im Puffer ist
– Invers ausgeben
• Aufrufen im
Hauptprogramm
Security - 04 Cryptology
#21
Prozedurale Programmierung
•
Zerlegen des Programms in
Prozeduren / Funktionen
– Wesentlich: Übergabe von
Parametern an Funktionen
•
Programm besteht aus
Sequenz von
Funktionsaufrufen
– Erste Funktion: main
•
Prozeduren können auch
globale Variablen verändern
– „Zustand“ über mehrere
Aufrufe hinweg
Security - 04 Cryptology
#22
Beispiel: Bankkonto
• Bankkonto hat einen Zustand...
– Kontostand
• ...und Operationen
– Einzahlen,
– Auszahlen,
– Kontostand erfragen
• Mögliche Implementierung?
Security - 04 Cryptology
#23
Problem:
Vergessen
der
Zuweisung
erzeugt
falsche
Semantik
#24
Ausgabe des Programms
#25
Etwas besser:
Verwendung
einer
statischen
Variable
#26
Ausgabe des Programms
#27
#28
Ausgabe des Programms
#29
Probleme prozeduraler Programmierung
• Bisher
– Aufteilung des Programms in Prozeduren mit bestimmten Aufgaben
– Hauptprogramm steuert Programmfluss über Funktionsaufrufe
– Übergabe von Daten über Parameter oder globale Variablen
• Probleme
– Verwendung globaler Variablen ist problematisch
– Ausführung einer Funktion abhängig vom Zustand (Inhalt) der globalen
Variable
– Man nennt dies auch „Seiteneffekt“
• Alternatives Konzept: Funktionale Programmierung
Security - 04 Cryptology
#30
Funktionale Programmierung
Funktionale Programmierung
• Inspiriert von
mathematischen
Funktionen
• Wir besprechen hier nur
die Grundidee
• Funktionale
Programmierung ist viel
mehr
• Es gibt auch „funktionale“
Programmiersprachen
Security - 04 Cryptology
#32
Funktionale Programmierung
• Mathematische Funktionen
sind wie eine große Tabelle
• Abhängig von den
Parametern, findet man das
(immer konstante) Ergebnis
in einer Tabelle
• Wichtiges Prinzip:
Termersetzung
– f(2)
– f(4)
4
16
Security - 04 Cryptology
#33
Funktionale Programmierung
• Vereinfacht dargestellt ist funktionale wie
prozedural ohne globale Variablen
• Denkweise ist sehr wichtig für gut testbare und
wartbare Programme
Security - 04 Cryptology
#34
Zusammenfassung und Ausblick
• Prozedurale und funktionale Programmierung hilft,
Programme besser wartbar, fehlerfreier, etc. zu machen
– Bringt keine weitere „Mächtigkeit“ der
Programmiersprache
– Mittel, um den Quelltext für Menschen besser verständlich
zu machen
• Prozedural: Aufteilen von Programmen in kleine,
handliche Prozeduren
– Dürfen auch globale Variablen verändern
• Funktional: Wie prozedural, nur ohne globale Variablen
#35
Herunterladen