C++ – ooP ? Arbeitsblatt 1 Prof. Dr. Gerhard Berendt SS 2002 1.1 Objekte, Werte, Typen, Variable. 1.2 Definition und Manipulation von Objekten. 1.3 Referenzen. Computer–Programme dienen dazu, in irgendeiner Form vorliegende Daten in den Rechner eingeben, manipulieren und wieder ausgeben zu können. Zu unterscheiden sind dabei die eigentlichen Operationen mit den Daten von den Methoden, mit denen diese Daten ein– und ausgegeben werden. Zum Verständnis der Struktur einer Programmsprache ist eine rudimentäre Kenntnis über den Mechanismus erforderlich, mittels dessen der Rechner die Daten annimmt und ausgibt und während der Rechenvorgänge aufbewahrt. Wenn man auf die Programmierung in Maschinensprache verzichtet, genügt es in den meisten Fällen, die Speicherverwaltung des Rechners in groben Zügen zu kennen. Hier zunächst die wichtigsten Begriffe kurz zusammengefasst: Vokabeln Kapitel 1 Objekt steht für einen Speicherbereich, in dem Daten abgelegt werden. Die Größe des Objekts liegt für dessen Lebensdauer fest, der Inhalt des zugehörigen Speicherbereiches kann jedoch verändert werden. Adresse Numerierung des Speichers. Die Adresse des ersten Bytes eines Objekts kann als Adresse des gesamten Objekts gewählt werden. Wert Der Inhalt eines Objektes ist ein Wert (genauer: ein l– Wert). 1 C++ – ooP ? Arbeitsblatt 1 Prof. Dr. Gerhard Berendt SS 2002 Typ eine Menge von Werten definierter Größe, üblicherweise assoziiert mit einer Anzahl von Operationen, die mit Objekten dieses Typs vorgenommen werden können. Typ–Konstruktor Funktion, die, angewandt auf einen Typ einen neuen Typ erzeugt (z.B. Referenz auf einen Typ). Variable Name in einem Programmtext, der ein Objekt bezeichnet. Konstante Direkt angegebene Werte in einem Programmtext (dies sind keine Objekte, d.h. sie liegen nicht in einem definierten Speicherbereich (sogenannte r–Werte). Anweisung Vorschrift, mit der u.a. ein Objekt zusammen mit einem zugehörigen Wert definiert werden kann. Syntax Kapitel 1 Definition einer Variablen (Anweisung): Typname Variablenname(Anfangswert); Alternativ: Typname Variablenname = Anfangswert; Werte können mit der Zuordnungsanweisung Ausdruck links (l–Wert erforderlich) = Ausdruck rechts (l– oder r–Wert); 2 C++ – ooP ? Arbeitsblatt 1 Prof. Dr. Gerhard Berendt SS 2002 verändert werden. Dabei wird der Inhalt des auf der linken Seite referierten Objekts zu dem auf der rechten Seite referierten Wert (ggf. unter Umwandlung in einen l– Wert) geändert. Definition einer Variablen vom Referenz–Typ (Referenzvariable): Typname& Variablenname(Ausdruck); Alternativ: Typname& Variablenname = Ausdruck; Dabei sollte der Ausdruck auf der rechten Seite ein Objekt des Typs Typname sein. Die Variable "Variablenname" wird dann an das durch "Ausdruck" referierte Objekt "gebunden". 1.4 Funktionen. Vokabeln Kapitel 1 Funktion Folge von Anweisungen, die eine bestimmte Aufgabe abarbeiten. In C++ ist der Definitionsbereich einer Funktion das kartesische Produkt einer endlichen Anzahl von Typen und der Wertevorrat ein einzelner Typ. Als Typen kommen z.B. auch Referenztypen in Frage. Funktionen können verschachtelt werden. 3 C++ – ooP ? Arbeitsblatt 1 Prof. Dr. Gerhard Berendt SS 2002 Syntax Kapitel 1 Definition einer Funktion: Rückgabetyp Funktionsname(Parameterliste) { Anweisungsliste } Falls die Funktion keinen Wert zurückgibt, ist der Rückgabetyp "void". Die Parameter in der Liste bestehen aus einer, durch Kommata getrennten Aufzählung der Variablentypen, optional von den jeweiligen (formalen) Parameternamen gefolgt. Die Klammern sind obligatorisch, auch wenn die Parameterliste leer ist. In der Anweisungsliste des in { } stehenden Funktionenkörpers muß – sofern der Rückgabetyp nicht "void" ist – mindestens eine Anweisung der Form return (Ausdruck); vorkommen. Falls der Rückgabetyp "void" ist, kann diese Anweisung wegfallen oder durch return; ersetzt werden. Aufruf einer Funktion: Funktionsname(Parameterausdruckliste); Dabei ist die Parameterausdruckliste eine durch Kommata getrennte Liste von Ausdrücken. Jeder Ausdruck muß aus einem Wert bestehen, der in der Parameterliste der Funktionsdefinition an der entsprechenden Stelle vom richtigen Typ ist. Zur Laufzeit wird ein Funktionsaufruf wie folgt ausgeführt: 4 Prof. Dr. Gerhard Berendt SS 2002 1. C++ – ooP ? Arbeitsblatt 1 Für jeden formalen Parameter der Funktion wird a) der zugehörige Parameterausdruck berechnet und b) mit dem Ergebnis wird ein neues Objekt des entsprechenden Typs initialisiert. Damit wird jeder aktuelle Parameter auf einen neuen Parameter vom gleichen Typ kopiert. 2. Die Anweisungen des Funktionskörpers werden ausgeführt. Dies geschieht in einer Umgebung, in der die folgenden Namen verfügbar sind: lokale Namen, z.B. Variable inklusive den Kopien der aktuellen Parameter, alle Namen, die in umfassenden Bereichen verfügbar sind. 3. Wenn eine return–Anweisung erreicht wird, wird der entsprechende Ausdruck ausgewertet und ein neues Objekt des zugehörigen Typs erzeugt und an das aufrufende Programm ausgegeben. 4. Der Speicherbereich, der bei dem Funktionsaufruf für die Kopien der aktuellen Parameter alloziert wurde, wird an das Programm zurückgegeben. Die Funktion benötigt also während ihres Ablaufs Speicherplatz, der als Aufrufrahmen bezeichnet wird. Funktionen in C++ übernehmen und übergeben Parameter als Kopien; das Verfahren wird als "call–by–value" bezeichnet. Eine Funktion kann mithin einen übergebenen Parameter nicht in modifizierter Form zurückgeben. Wenn das erreicht werden soll, dann muß dieser Parameter als Referenz in der formalen Parameterliste übergeben werden: In Schritt 1. wird dann der hierbei initialisierte Parameter an den zugehörigen aktuellen Parameter gebunden; wird er nun während des Ablaufs der Funktion modifiziert, dann geschieht das gleiche mit dem aktuellen Parameter. Wird schließlich in Schritt 4. der Referenzparameter vernichtet, dann überlebt der aktuelle Parameter den Funktionsaufruf in der zuvor modifizierten Form: hier findet also ein "call–by– address" statt. Auch der Rückgabetyp einer Funktion kann ein Referenztyp sein; dies lässt die Möglichkeit offen, dass das Ergebnis der Funktion auf einen der (ebenfalls als Referenztyp übergebenen) Funktionsparameter zugreift, ohne dass befürchtet werden muß, dass dieser Parameter nach Abschluß des Funktionsaufrufes gar nicht mehr existiert. Beispiel: 5 Prof. Dr. Gerhard Berendt SS 2002 C++ – ooP ? Arbeitsblatt 1 Wir wollen eine Funktion f betrachten, die als Argumente zwei ganze Zahlen n und m hat und beide Argumente um eins vergrößert. Der Teil des Quelltextes, in dem die Funktion definiert wird, könnte die folgende Form haben: . . . . . . . . void f(int n, int m) //d.h. kein Rückgabewert { n=n+1; m = m+1; return; } . . . . . . . . Wollen wir diese Funktion im Hauptteil des Programms für a = 4 und b = 7 auswerten, dann sähe das etwa so aus: int a(4); int b(7); . . . . . . . . f(a,b); . . . . . . . . -> // Ergebnis . . . . Würde man an der durch den Pfeil gekennzeichneten Stelle des Programms die Zahlen a und b ausgeben, dann erhielte man als Ergebnis die Werte a = 4 und b = 7, da die Funktion f in ihrem Aufrufrahmen nur lokale Kopien von a und b erzeugt, diese dort um jeweils eins vergrößert und sie beim Verlassen des Aufrufrahmens wieder löscht. Hätten wir f jedoch beispielsweise durch 6 Prof. Dr. Gerhard Berendt SS 2002 C++ – ooP ? Arbeitsblatt 1 void f(int n, int& m) { n=n+1; m = m+1; return; } definiert, dann wird beim Aufruf von f nur a lokal kopiert und – nach Vergrößerung um eins – beim Verlassen des Funktionskörpers gelöscht, während die Referenz auf b (und damit auch b selbst) nach der Erhöhung um eins den neuen Wert auch nach dem Verlassen des Aufrufrahmens von f beibehält. Das ausgegebene Ergebnis wäre mithin a = 4 und b = 8 . Übungen: 1.1 Betrachten Sie das folgende Fragment eines C++ Programms: . . . int x(5), f(0); int& y = x; y = 8; f = x * x; . . . Welchen Wert hat die Variable f an dieser Stelle ? 1.2 Warum gibt der C++ Compiler beim Kompilieren des folgenden Fragments eine Fehlermeldung aus ? . . . int x(10), y(23); int max(int& a, int& b) { if (a>b) return a; 7 Prof. Dr. Gerhard Berendt SS 2002 C++ – ooP ? Arbeitsblatt 1 else return b; } max(x,y) = 26; . . . Wie kann der Fehler behoben werden ? 1.3 Eine Funktion der zwei ganzzahligen Variablen x und y soll die neuen Variablen u = x + y und v = x * y ausgeben. Wie kann diese Funktion in C++ aussehen ? 8