© GMSP 2011 Pascal C++ Java Python
© GMSP 2011 Pascal C++ Java Python
Allgemeines        
Paradigma imperativ imperativ imperativ imperativ
Merkmale plattformabhängig kompilierend, statisch typisiert, Speicherbelegung und -Freigabe bis auf die Verwendung von Zeigern automatisch plattformabhängig kompilierend, statisch typisiert, Speicherbelegung und -Freigabe wegen intensiver Zeigernutzung vollständig manuell in plattformunabhängigen Bytecode kompilierend, statisch typisiert, Speicherbelegung und -Freigabe ausschließlich automatisch mittels "GarbageCollector" interpretierend, dynamisch typisiert, Speicherbelegung und -Freigabe ausschließlich automatisch
Anwendungsbereiche Ausbildungssprache, mit Erweiterungen in Delphi® textbasierte rechenintensive Anwendungen, Betriebssysteme, hardwarenahe Anwendungen möglich graphikbasierte Anwendungen, plattformunabhängige Programme, Web-Anwendungen minimalistische, übersichtliche Skriptsprache, auch im serverseitigen Einsatz
Dateiname Name beliebig, Suffix .p oder .pas Name beliebig, Suffix .cpp oder .c++ Name muss dem Namen der Klasse entsprechen, Suffix .java Name beliebig, Suffix .py
Groß-/Kleinschreibung wird nicht unterschieden wird streng unterschieden wird streng unterschieden wird streng unterschieden
Konventionen Schlüsselwörter groß, Bezeichner in CamelCase, häufig in ungarischer Notation, eine Anweisung pro Zeile lange Bezeichner durch "_" strukturiert, häufig in ungarischer Notation, eine Anweisung pro Zeile Klassennamen stets mit großem Anfangsbuchstaben, Methoden- und Attributnamen mit kleinem Anfangsbuchstaben, Bezeichner in CamelCase, Konstanten nur mir Großbuchstaben, eine Anweisung pro Zeile siehe Syntax
Syntax Semikolon als Trenner zwischen zwei Anweisungen. Ende des Hauptprogramms durch "." Semikolon als Anweisungensende Semikolon als Anweisungensende Zeilenumbruch als Anweisungsende, Blockbildung durch Einrücken
Strukturierung prozedurale Programmierung durch Unterprogramme und Funktionen beliebige Mischung von prozeduraler Programmierung mit Funktionen und objektorientierter Programmierung mit Klassen und Methoden rein objektorientierte Programmierung mit Klassen und Methoden objektorientierte Programmierung mit Klassen und Methoden; durch implizite Instanziierung der Klasse __main__ kann prozedurale Programmierung mit Funktionen simuliert werden
Block        
BEGIN ... END { ... } { ... } Einrückung der Quelltextzeilen
Kommentare        
{ ein- oder mehrzeilig } // einzeilig /* verteilt über mehrere Zeilen */ // einzeilig /* verteilt über mehrere Zeilen */ /** JavaDoc Kommentar **/ # nur einzeilig
Standard-Datentypen _1 _2, 3, 4 _5, 6 _7
BOOLEAN TRUE/FALSE bool true/false boolean true/false bool True/False
byte 1 Byte lange Ganzzahl
short 2 Byte lange Ganzzahl short 2 Byte lange Ganzzahl
INTEGER 2 Byte lange Ganzzahl int 1 Wort lange Ganzzahl int 4 Byte lange Ganzzahl int 4 Byte lange Ganzzahl
LONGINT 4 Byte lange Ganzzahl long 1-2 Wort lange Ganzzahl long 8 Byte lange Ganzzahl long beliebig lange Ganzzahl
long long 2-4 Wort lange Ganzzahl
REAL 4 Byte lange Fließkommazahl float 1 Wort lange Fließkommazahl float 4 Byte lange Fließkommazahl
EXTENDED 10 Byte lange Fließkommazahl double 2 Wort lange Fließkommazahl double 8 Byte lange Fließkommazahl float 8 Byte lange Fließkommazahl
long double 2-4 Wort lange Fließkommazahl
complex komplexe Zahl
CHAR 1 Byte char 1 Byte char 2 Byte(Unicode)
STRING Zeichenkette, 256 Byte lang, 1 Byte pro Zeichen, effektiv genutzte Länge an erster Stelle char * Zeichenkette, Zeiger auf das erste Zeichen eines mit NUL terminierten Speicherbereichs String Unicode-Zeichenkette (kein Standarddatentyp, sondern abgeleitete finale Klasse) str unveränderbare Sequenz von Zeichen (initialisierbar als kurze oder lange Zeichenkette oder als "Raw-String")
string Klasse für beliebig lange Zeichenketten (kein Standarddatentyp, aber wesentlich einfacher zu handhaben als char *) unicode Unicode-Zeichenkette
ARRAY [m .. n] OF T Folge fester Länge (n-m+1) beliebiger Werte vom Typ T T[] Folge beliebiger Werte vom Typ T, deren feste Länge spätestens bei der Initialisierung gesetzt wird T[] Folge beliebiger Werte vom Typ T, deren feste Länge spätestens bei der Initialisierung gesetzt wird tuple unveränderbare Sequenz beliebiger Werte
list veränderbare Sequenz beliebiger Werte
SET OF S Menge beliebiger Werte, die der aufzählbaren Spezifikation S genügen set veränderbare Menge beliebiger Werte
frozenset unveränderbare Menge beliebiger Werte
dict Abbildung eindeutiger Schlüssel auf beliebige Werte
NoneType entfernt Wert und dynamische Typisierung
  1. Pascal unterstützt nur Zeichenketten mit Maximallänge 255, während die übrigen Sprachen in den Grenzen des verfügbaren Arbeitsspeichers beliebige Längen gestatten
  2. da C++ eine Erweiterung von C ist, bilden die Datentypen eine Obermenge der aus C bekannten Strukturen
  3. der genaue Wertebereich der numerischen Datentypen hängt in C++ von der genutzten Rechnerarchitektur ab
  4. durch die "Standard Template Library" (STL), die Bestandteil von C++ ist, werden weitere Datentypen bereitgestellt, insbesondere auch Klassen für set und map
  5. zum Standardumfang von Java gehört eine sehr umfangreiche Klassenbibliothek, die neben der oben genannten Klasse String auch Schnittstellen für Set und Map definiert und diese in verschiedenen Varianten implementiert
  6. zu den Standarddatentypen in Java existiert jeweils auch eine Hüllklasse, deren Name in der Regel dem Typnamen mit großem Anfangsbuchstaben entspricht
  7. der Wertebereich der beliebig langen Ganzzahl ist nur durch die Menge verfügbaren Arbeitsspeichers begrenzt
Programm-Aufbau        
PROGRAM Test; {Deklarationsteil} {Konstanten} {benutzerdef. Datentypen} {globale Variablen} {Funktionen und Prozeduren} {Anweisungsteil} BEGIN writeln('Hallo!') END. /* Einbindung von Bibliotheken */ #include <iostream> #include <iomanip> /* Festlegung des benutzten Gültigkeitsbereichs */ using namespace std; /* Deklarationen aller Art in bel. Reihenfolge */ // Hauptprogramm "Test" int main(int argc, char * const argv[]) { cout << "Hallo!" << endl; } /* Raum zur Einbindung von Paketen mittels import */ /* Raum zur Festlegung des eigenen Pakets*/ public class Test { /* Deklarationen aller Art in bel. Reihenfolge */ // Hauptprogramm "Test" public static void main(String[] args) { System.out.println("Hallo!"); } } ################################## # Interpreter-Anweisungen, etwa # # zur genutzten Textcodierung # ################################## # -*- coding: utf-8 -*- # Skriptprogramm "Test" print "Hallo!" + '\n'
Deklaration und Wertzuweisung Variablen 1 Variablen/Attribute 2 Attribute 3 Attribute/Variablen 4
VAR i: INTEGER; n: LONGINT; x: REAL; y: EXTENDED; c: CHAR; s: STRING; a: ARRAY [0 .. 9] OF CHAR; m: SET OF '0' .. '9'; BEGIN i := 4711; n := 1234567890; x := 3.14159; y := 1.6e-19; c := 'A'; s := 'Pascal'; a[0] := 'T'; { für 1 .. 9 entsprechend } m := ['1', '3', '5', '7', '9'] END. { float x; double y; char c; char a[10]; int i = 4711; long n = 1234567890L; x = 3.14159F; y = 1.6e-19; c = 'A'; const char *s = "C++"; a[0] = 'T'; // für 1 .. 9 entsprechend } { float x; double y; char c; String s; char[10] a; int i = 4711; long n = 1234567890L; x = 3.14159F; y = 1.6e-19; c = 'A'; s = "Java"; a[0] = 'T'; // für 1 .. 9 entsprechend } i = 4711 n = 1234567890L y = 1.6e-19 z = 0 + 1.5j # Real- + Imaginärteil c = 'A' s = "Python" # Löschen mit s = None t = ('T', 'e', 's', 't') # Tupel l = [1, '+', 2.14, "Summe"] # Liste m = set ("Otto") # Menge {'O', 't', 'o'} d = {"sun":"Sonne", "moon":"Mond"}
  1. in Pascal erfolgt die Deklaration der Variablen vor dem Anweisungsblock; man unterscheidet die globale und lokale Deklaration
  2. in C++ kann die Deklaration der Variablen/Attribute an beliebiger Stelle im Quelltext erfolgen, jedoch ist die Gültigkeit stets auf den umschließenden Block begrenzt
  3. in Java kann die Deklaration der Attribute an beliebiger Stelle im Quelltext erfolgen sofern diese Stelle innerhalb einer Klasse liegt; die Gültigkeit ist stets auf den umschließenden Block begrenzt
  4. Python kennt keine explizite Deklaration von Attributen/Variablen; die Typisierung erfolgt dynamisch mit der ersten Wertzuweisung, wobei die Gültigkit stets auf die umschließende Methode begrenzt ist (außer man verwendet explizit das Schlüsselwort global)
Benutzerdef. Datentypen        
TYPE Person = RECORD name: STRING; idNr: INTEGER END; VAR buerger: Person; BEGIN buerger.name := "Hans Mustermann"; buerger.idNr := 4711 END. typedef struct Person { const char *name; int id_nr; } t_person, *p_person; p_person buerger = new t_person; buerger->name = "Hans Mustermann"; buerger->id_nr = 4711; Als rein objektorientierte Sprache erlaubt Java nur die Definition benutzerdefinierter Klassen. ########################################## # Obwohl Python eine objektorientierte # # Sprache ist, kann durch Verwendung # # eines Tupels ein benutzerdefinierter # # Datentyp nachgestellt werden. # ########################################## buerger = (name, idNr) = ("Hans Mustermann", 4711)
Benutzerdef. Klassen        
Objektorientierung ist nicht Bestandteil der Standard Pascal-Spezifikation, jedoch existieren "Object Pascal" Erweiterungen der Sprache, z.B. Delphi class Person { sting name; int id_nr; public: Person(const string nm, int id) { name = nm; id_nr = id; } ~Person() {} // leerer Destruktor }; Person *buerger = new Person("Hans Mustermann", 4711); delete buerger; // zur Freigabe class Person { String name; int idNr; public Person(String nm, int id) { name = nm; idNr = id; } } Person buerger = new Person("Hans Mustermann", 4711); class Person: def __init__(self, name, idNr): self.name = name self.idNr = idNr buerger = Person("Hans Mustermann", 4711)
Operatoren        
Vorzeichen + - + - + - + -
Fließkomma-Arithm. + - * / + - * / Vorsicht: mehrdeutiger Divisionsoperator + - * / Vorsicht: mehrdeutiger Divisionsoperator + - * / ** Python kennt zusätzlich den Potenzoperator "**"
Vorsicht: mehrdeutiger Divisionsoperator
Ganzzahl-Arithm. + - * DIV MOD + - * / % + - * / % + - * / % **
Bit-Arithm. NOT AND OR XOR SHR SHL ~ & | ^ << >> Shift-Operatoren auch zur Aus- und Eingabe mit Streams genutzt ~ & | ^ << >> <<< >>> zusätzliche Vorzeichen erhaltende Variante der Shift-Operatoren ~ & | ^ << >>
Zuweisung := = ++ -- += -= *= /= %= = ++ -- += -= *= /= %= = += -= *= /= %=
Vergleiche = <> < > <= >= == != < > <= >= == != < > <= >= == != < > <= >=
Aussagenlogik NOT AND OR diese Operatoren verwenden vollständige Auswertung ! && || Vorsicht: diese Operatoren verwenden ausschließlich Kurzschlussauswertung ! && || ^ & | Java kennt zusätzlich Xor; die zweite Variante von Und, Oder nutzt vollständige Auswertung not and or Vorsicht: diese Operatoren verwenden ausschließlich Kurzschlussauswertung
Datenzugriff . . * -> . .
Speicherallokation implizit durch Zuweisung new delete & plus Freigabe- und Address-Op. new implizit durch Zuweisung
Typumwandlung nicht allgemein vorgesehen (T) var (T) var T(var)
Ein-/Ausgabe        
VAR num: INTEGER; write('Eingabe:'); readln(num); write('Ausgabe: ', num); writeln('Ausgabe: ', num); {line feed} int num; cout << "Eingabe: "; cin >> num; cout << "Ausgabe: " << num; cout << "Ausgabe: " << num << endl; int num; System.out.print("Eingabe: "); try { BufferedReader cin= new BufferedReader( new InputStreamReader(System.in)); num = Integer.parseInt(cin.readLine()); } catch(IOExeption e) { } System.out.print("Ausgabe: "); System.out.println(num); // Im Applet über eigene TextFelder ! num = input("Eingabe: ") print "Ausgabe: ", num print "Ausgabe: ", num, '\n' # line feed
Verzweigungen _1 _2 _2  
IF (x <> 0) { einseitig } THEN write(7/x) IF (a MOD 2 = 0) { zweiseitig } THEN write('gerade') ELSE write('ungerade'); if (x != 0) // einseitig cout << 7/x; if (a % 2 == 0) // zweiseitig cout << "gerade"; else cout << "ungerade"; if (tag == 1) // mehrseitig cout << "Montag"; else if (tag == 2) cout << "Dienstag"; // ... else if (tag == 7) { cout << "Sonntag, "; cout << "Tag der Ruhe"; } else cout << "Fehler"; if (x != 0) // einseitig System.out.print(7/x); if (a % 2 == 0) // zweiseitig System.out.print("gerade"); else System.out.print("ungerade"); if (tag == 1) // mehrseitig System.out.print("Montag"); else if (tag == 2) System.out.print("Dienstag"); // ... else if (tag == 7) { System.out.print("Sonntag, "); System.out.print("Tag der Ruhe"); } else System.out.print("Fehler"); if x != 0: # einseitig print 7/x if a % 2 == 0: # zweiseitig print "gerade" else print "ungerade" if tag == 1: # mehrseitig print "Montag" elif tag == 2: print "Dienstag" # ... elif tag == 7: print "Sonntag, ", print "Tag der Ruhe" else: print "Fehler"
  1. In Pascal ist das Semikolon ein Trenn-Zeichen zwischen zwei Anweisungen, daher darf vor "ELSE" kein Strichpunkt stehen
  2. In C++ und Java ist das Semikolon das End-Zeichen einer Anweisung, daher muss vor "else" ein Strichpunkt stehen
Fall-Unterscheidung        
CASE tag OF 1 : write('Montag'); 2 : write('Dienstag'); { ... } 7 : BEGIN write('Sonntag, '); write("Tag der Ruhe") END; OTHERWISE : writeln('Fehler'); END; switch (tag) { case 1 : cout << "Montag"; break; case 2 : cout << "Dienstag"; break; // ... case 7: cout << "Sonntag, "; cout << "Tag der Ruhe"; break; default: cout << "Fehler" << endl; } switch (tag) { case 1 : System.out.print("Montag"); break; case 2 : System.out.print("Dienstag"); break; // ... case 7: System.out.print("Sonntag, "); System.out.print("Tag der Ruhe"); break; default: System.out.println("Fehler"); } siehe mehrfache Verzweigung
Zählschleifen        
FOR i := 0 TO 8 DO sum := sum + i; FOR k := 9 DOWNTO 1 DO pro := pro *2; FOR ziffer := 1 TO 9 DO IF ziffer in [2,3,5,7] THEN write(ziffer * ziffer); for (i = 0; i < 9; i++) sum = sum + i; for (k = 9; k > 0; k--) pro *= 2; // Kurzform int nums[] = {2, 3, 5, 7}; int anzahl = 4; for (int *zeiger = nums; zeiger <= ;<nums[anzahl-1]; zeiger++) cout << (*zeiger) * (*zeiger) << endl; for (i = 0; i < 9; i++) sum = sum + i; for (k = 9; k > 0; k--) pro *= 2; // Kurzform int[] range = {2, 3, 5, 7}; for (int ziffer : range) System.out.print(ziffer * ziffer); for i in range(0,10): sum = sum + 1 for k in range(9,0,-1): pro *= 2 for ziffer in (2,3,5,7): print ziffer ** 2
Schleife mit Anfangs-Bedingung        
WHILE (a > 0) DO BEGIN b := b * 2; a := a - b; END; while (a > 0) { b = b * 2; a = a - b; } while (a > 0) { b = b * 2; a = a - b; } while a > 0: b = b * 2 a = a - b
Schleife mit End-Bedingung        
REPEAT a := a + 12; b := 2 * a; UNTIL b > 1000; do { a = a + 12; b = 2 * a; } while (b <= 1000); do { a = a + 12; b = 2 * a; } while (b <= 1000); a = a + 12 # Hilfskonstruktion, da Befehl b = 2 * a # in Python nicht verfügbar while b <= 1000: a = a +12 b = 2 * a
Substrukturen Funktionen, Unterprogramme Funktionen, Methoden Methoden Methoden, Funktionen
PROCEDURE tausche(VAR a:real; VAR b:real); VAR hilf :real; BEGIN hilf := a; a := b; b := hilf { TrennZeichen ; unnötig } END; FUNCTION f(x:integer) : extended; BEGIN f := sqrt(x) END; void tausche(float& a, float& b) { // & bezeichnet Referenzparameter float hilf; hilf = a; a = b; b = hilf; // EndZeichen ; nötig } double f(short x) { return sqrt(x); } void tausche(Float a, Float b) { // großes F Float hilf; hilf = a; a = b; b = hilf; // EndZeichen ; nötig } double f(short x) // Verwendung der Klasse Math { return Math.sqrt(x); } def tausche(x, y): # es gibt nur Funktionen return y,x import math # Modul für math. Funktionen def f(x): return math.sqrt(x)
Vollständiges Programm        
PROGRAM Primzahltest; VAR zahl: INTEGER; FUNCTION prim(nn: INTEGER):BOOLEAN; VAR OK: BOOLEAN; k : INTEGER; BEGIN ok := (nn > 1) AND (nn MOD 2 <> 0); k := 3; WHILE (k*k <= nn) DO BEGIN ok := ok AND (nn MOD k <> 0); k := k + 2; END; prim := (nn = 2) OR ok END; BEGIN write('Zahl = "); read(zahl); IF prim(zahl) THEN writeln(zahl, ' ist eine Primzahl) ELSE writeln(zahl, ' ist keine Primzahl) END. { Eingabe: Zahl = 49 } { Ausgabe: 49 ist keine Primzahl } // Demo-Programm Primzahltest // -------------------------- # include <iostream> # include <iomanip> using namespace std; bool prim(int nn) { bool ok = (nn > 1) && (nn % 2 != 0); int k = 3; while (k*k <= nn) { ok = ok && (nn % k != 0); k = k + 2; } return (nn == 2) || ok; } int main(int argl, const char *argv[]) { int zahl; cout << "Zahl = "; cin >> zahl; cout << zahl; if (prim(zahl)) { cout << " ist eine Primzahl" << endl; } else { cout << " ist keine Primzahl"<< endl; } return 0; } // Eingabe: Zahl = 49 // Ausgabe: 49 ist keine Primzahl package primzahltest; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class Main { public static boolean prim(int nn) { boolean ok = (nn > 1) && (nn % 2 != 0); int k = 3; while (k*k ;< = nn) { ok = ok && (nn % k != 0); k = k + 2; } return ok || (nn == 2); } public static void main(String[] args) { int zahl=0; System.out.print("Zahl = "); try { BufferedReader cin= new BufferedReader( new InputStreamReader(System.in)); zahl = Integer.parseInt(cin.readLine()); } catch (IOException e) { } System.out.print(String.valueOf(zahl)); if (prim(zahl)) { System.out.println(" ist Primzahl"); } else { System.out.println(" ist keine Primzahl"); } } } // Eingabe: Zahl = 49 // Ausgabe: 49 ist keine Primzahl # Demo-Programm Primzahltest # -------------------------- # -*- coding: utf-8 -*- def prim(nn): ok = (nn > 1) and (nn % 2 != 0) k = 3 while k*k <= nn: ok = ok and nn % k != 0 k = k + 2 return (nn == 2) or ok def main(): zahl = input("Zahl = ") if prim(zahl): print zahl, " ist eine Primzahl" else: print zahl, " ist keine Primzahl" main() # Eingabe: Zahl = 49 # Ausgabe: 49 ist keine Primzahl

Valid XHTML 1.0 Strict