User:Patrick0Moran/DictionaryProject


In der statistischen Mustererkennung werden mehrdimensionale Merkmalsvektoren benutzt. Seine Boden auflösung betrug ca.

Navigation menu


Wenn Sie wollen, können Sie ganze Zahlen auch im Hexadezimalformat angeben. Für einzelne Zeichen verwendet man das einfache Hochkomma, also z. Diese Konstante kann man dann einer Variable vom Typ char zuweisen. Implizite Typumwandlung Meistens kann man Variablen und Konstanten verschiedener Datentypen einander zuweisen. Als Programmierer sollten Sie aber ein wenig die dabei angewandten Prinzipien kennen, um beurteilen zu können, ob die automatische Umwandlung auch die ist, die Sie wollen.

Vorsicht ist beim umgekehrten Fall geboten. Hierbei können Informationen verloren gehen und sogar völlig andere Ergebnisse herauskommen, als Sie vielleicht erwarten. Wenn noch Konstanten im Quelltext stehen, kann man von Hand nachrechnen und aufmerksam werden.

Wenn aber andere Variablen beteiligt sind, wird das schon schwieriger, zum Beispiel: Bei der gegenseitigen Zuweisung von ganzen und Dezimalzahlen sind nicht so viele Fallstricke ausgelegt. Sie sollten lediglich daran denken, dass der gesamte Teil nach dem Komma abgetrennt wird, wenn Sie als Ergebnis eine Ganzzahl angeben. Jede Variable muss über einen eindeutigen Typ verfügen, und bei Zuweisungen und Vergleichen müssen die Variablen beziehungsweise Konstanten als kompatibel bekannt sein, sonst wird eine Fehlermeldung ausgegeben.

Überhaupt weist Sie der Compiler mit Hilfe von Warnungen oft auf mögliche Fehler oder Mehrdeutigkeiten hin, etwa wenn er annimmt, dass Sie eine Anweisung anders gemeint haben, als sie nun im Quelltext steht.

Lesen Sie diese Meldungen aufmerksam und versuchen Sie stets die Ursachen dafür zu verstehen. Auf diese Weise werden Sie auch viel über die richtige Programmierung lernen. Explizite Typumwandlung Anstatt sich auf die automatische Typkonvertierung zu verlassen, kann es auch manchmal sinnvoll sein, dem Compiler eine Regel zur Umwandlung vorzuschreiben.

Für die explizite Typumwandlung verwenden die C-Programmierer einen sehr bildlichen Ausdruck, nämlich cast , das englische Wort für Gipsverband. Die andere Möglichkeit ist, die Variable in Klammern zu setzen und den Typ davor: Da Sie aber erst noch einige weitere Begriffe kennen müssen, um diese zu verstehen, verschieben wir die Diskussion auf später Seite. Aufzählungstypen Nicht immer sind numerische Werte für eine Variable sinnvoll. Manchmal will man für sie nur einen begrenzten Wertebereich zulassen.

Hier sollten Sie einen Aufzählungstyp verwenden. Sie deklarieren ihn mit dem Schlüsselwort enum , einem Typnamen und einer Liste von Werten, eingeschlossen in geschweiften Klammern und getrennt durch Kommas. Für unseren Status können wir schreiben: Operatoren Variablen alleine nützen noch nicht viel. Man muss sie auch miteinander verknüpfen, sie zuweisen, verändern und ausgeben können.

Dazu dienen die Operatoren. Einige erinnern noch daran, dass C einmal als besonders hardwarenahe Sprache entworfen wurde. Überblick Auf jeden einzeln einzugehen, würde an dieser Stelle zu weit führen. Ich will Ihnen daher in Tabelle Tab: Operatoren eine Liste mit den wichtigsten Operatoren geben. Wenn Ihnen Verschiedene nicht gleich klar sind, müssen Sie sich deshalb keine Sorgen machen: Tatsächlich gibt es ein paar Operatoren, deren Bedeutung vom Kontext abhängt, in dem sie verwendet werden.

Für den Augenblick ist es hilfreich, wenn Sie die Quelltexte sehr konzentriert durchsehen und sich bei jeder Anweisung nach deren Bedeutung fragen. Dort regelt beispielsweise der Grundsatz Punkt vor Strich, dass zunächst multipliziert und dann erst addiert wird. Auch innerhalb jeder Gruppe kann es noch Reihenfolgen geben. Sie können nämlich sowohl vor als auch hinter der Variablen stehen, auf die sie wirken.

Man nennt diese beiden Stellungen auch Präfix und Postfix. Die Operatoren werden meist nicht als einziger Bestandteil einer Anweisung verwendet, sondern in kompliziertere Ausdrücke eingebaut.

Steht der Operator vor der Variable, wird er zuerst ausgeführt und dann erst der Ausdruck ausgewertet. Steht er dagegen dahinter , wird erst der gesamte Ausdruck ausgewertet und dann der Operator angewandt. Anfänger empfinden diese Schreibweise stets als verwirrend; die erfahrenen Programmierer sehen sie dagegen als besonders elegant und kompakt an. Überlegen oder probieren Sie mal selbst, welche Ausgabe der folgende Code erzeugt: Der Bedingungsoperator Einer der Operatoren, die in Tabelle fehlen, ist?: Er hat folgende allgemeine Form: Ausdruck2 Die Verwendung ist ganz einfach: Ist die Bedingung wahr, wird Ausdruck1 ausgewertet, ist sie falsch, dann Ausdruck2.

Ausdrücke Gerade war schon von Ausdrücken die Rede. Was ist eigentlich ein Ausdruck? Dem Begriff des Ausdrucks engl. Dieser hängt von den beteiligten Variablen und Operatoren ab. Betrachten wir beispielsweise folgende Variablen: Zusammenfassung Aus diesem Abschnitt sollten Sie sich Folgendes merken: Kommentare können auf zwei Arten in den Programmtext eingefügt werden: Jedes Programm sollte mindestens so viele Kommentar- wie Anweisungszeilen enthalten. Eine automatische Initialisierung erfolgt nicht.

Als Typen für Ganzzahlen gibt es je nach Wertebereich short , int und long. Die Typen char , short , int und long können den Zusatz unsigned erhalten.

Der Datentyp void steht für einen nicht existenten Wert. Wenn die Datentypen innerhalb eines Ausdrucks nicht kompatibel zueinander sind, versucht der Compiler, die Variablen selbstständig in einen anderen Typ umzuwandeln. Um auf diesen Vorgang Einfluss zu nehmen, können Sie auch explizit Typkonvertierungen vorschreiben. Der Typ des Werts eines arithmetischen Ausdrucks wird bestimmt von dem höchstwertigen Teilausdruck. Daten und Objekte werden mit Hilfe von Operatoren verknüpft, verändert und ausgelesen.

Übungsaufgaben Was passiert, wenn man einer Variablen vom Typ int eine Zahl mit Dezimalstellen zuweist? Welchen Wert hat eine Variable, nachdem sie deklariert wurde? Erklären Sie den Unterschied zwischen expliziter und impliziter Typkonvertierung. Die Funktion sizeof hat den Zweck, den Speicherverbrauch eines Datentyps oder einer Variablen zu bestimmen. Welche Ausgabe liefert folgendes Programm?

Für eine Variable x soll ausgegeben werden, ob sie 0 ist oder nicht. Was ist hier falsch? Dabei spielt natürlich auch eine Rolle, dass es sich dabei um freie Software handelt, der Compiler also kostenlos erhältlich ist. Installation Sie können sich stets mit der neuesten Version des Compilers aus dem Internet versorgen, am besten von gcc.

Allerdings werden Sie dazu kaum je Anlass verspüren. In jeder Linux-Distribution ist nämlich dieser Compiler enthalten -- schon allein deshalb, weil er zum Kompilieren des Linux-Kernels gebraucht wird. Erscheint eine neue Version, bringen die Hersteller der Distributionen sie meist relativ schnell in die Form von Installationspaketen, die Sie dann nur noch von den Sites der Hersteller herunterladen müssen.

Die eigentliche Installation auf Ihrem Rechner ist dann mit den jeweiligen grafischen Werkzeugen oder mit rpm leicht zu erledigen. Wenn Ihr Programm aus mehreren Quelltextdateien besteht, können Sie auch mehrere hintereinander angeben. Dabei dürfen die Dateien auch in mehreren Verzeichnissen liegen, müssen Sie dazu nur jeweils den vollständigen Pfad angeben, zum Beispiel: Die wichtigsten sind in Tabelle zusammengefasst; ich werde sie Ihnen im Folgenden kurz erläutern. Die Reihenfolge, in der Sie die Optionen angeben, ist völlig egal.

Sie müssen lediglich sicherstellen, dass jeweils eine Option und ihr zugehöriger Parameter zusammen stehen. Name für die ausführbare Datei Vermutlich sind Sie mit dem Namen a. Debug-Informationen Jeder Programmierer macht Fehler. Um diese aufzudecken, gibt es Debugger vom englischen Wort bug, das eigentlich Käfer, umgangssprachlich auch Programmierfehler bedeutet; ob man in den ersten riesigen Elektronenhirnen mal tatsächlich Käfer fand, ist nicht zweifelsfrei überliefert.

Debugger sind Hilfsprogramme, mit denen Sie das Programm quasi beim Ablauf beobachten können, also an bestimmten Stellen stoppen, Werte von Variablen ausgeben oder um einzelne Schritte weiterlaufen lassen können. Damit der Debugger die Anweisungen im ausführbaren Programm den Quelltextzeilen zuordnen kann, braucht er entsprechende Informationen.

Diese werden durch die Option -g in das Programm eingefügt. Fehler und Warnungen Bei Syntaxfehlern also Verletzung der Sprachregeln stoppt der Compiler meist sofort und gibt die Datei sowie die Nummer der Codezeile aus, in der er den Fehler festgestellt hat.

Wenn Sie wie in folgendem Beispiel ein Semikolon vergessen: Manchmal wird ein Syntaxfehler aber gar nicht als solcher erkannt, da die Anweisung in einem anderen Kontext durchaus korrekt sein könnte.

Eine solche Fehlerinterpretation verwirrt den Compiler dann bei der Übersetzung der nachfolgenden Anwendungen so sehr, dass es meist Fehlermeldungen hagelt.

Wenn Sie an der ersten Stelle, an der ein Problem auftrat, nichts finden können, sollten Sie daher auch die Zeilen darüber betrachten, ob sich in diesen nicht die Ursache finden lässt. Anders verhält es sich mit Warnungen. Diese sind nicht so schwer wiegend, dass dadurch der Übersetzungsvorgang gleich eingestellt werden müsste.

Andererseits handelt es sich dabei um potenzielle Probleme, die im einfachsten Fall ignoriert werden, im schwersten Fall aber zur Laufzeit einige unerwünschte Effekte hervorrufen können. So weist Sie der Compiler darauf hin, dass Sie etwas unschön geschrieben haben oder mehr als nötig, dass er etwas anders auffasst, als Sie es vermutlich gemeint haben, und so weiter.

Für fast jede Warnung gibt es eine eigene Option, jeweils von der Form -W warnungs-typ. Zum Glück gibt es aber auch Schalter, die ganze Gruppen von Warnungen aktivieren. Eine ist dabei besonders wichtig: Mit -Wall schalten Sie alle Warnungen ein, die auf unschönen Code hindeuten. Dabei handelt es sich beispielsweise um nicht oder unzureichend initialisierte Variablen, Typverwechslungen, missverständliche Klammerungen oder unbenutzte Variablen.

Sie sollten die Warnungen ernst nehmen und solchen Code vermeiden. Wenn wir etwa schreiben: Sie sehen daran auch, dass Sie der Compiler bei einem Durchlauf nicht auf alles gleichzeitig hinweist. Hier ist beispielsweise die Variable p genauso unbenutzt wie s , wird jedoch nicht angemahnt. Erst wenn Sie s entfernen würden, käme die Warnung für p. Die Schreibweise -Wall steht zwar für warnings, all, ist aber nicht zufällig auch als wall, also Wand, zu lesen.

Sie können sich dabei eine Schutzmauer um Ihren Code vorstellen; wenn er sie überwindet, ist er schon mal in ganz guter Verfassung. Daher empfehle ich Ihnen, diesen Schalter immer zu verwenden. Kompilierung zur Objektdatei Wenn Sie Programme schreiben, die aus mehreren Dateien bestehen, so geben Sie diese üblicherweise nicht alle auf einmal beim Aufruf des Compilers an. Wenn Sie nämlich in einer davon einen Fehler gefunden haben, diesen korrigieren und die Übersetzung neu starten, werden auch alle davor stehenden nochmals kompiliert.

Bei Programmen mit mehr als einer Quelldatei darf man die einzelnen Quellen nur bis zum Objektcode übersetzen -- und das jeweils mit einem eigenen Compileraufruf für jede Datei. Sind alle Files übersetzt, können sie mit einem weiteren Aufruf zusammengelinkt werden. Um den Compiler anzuweisen, beim Objektcode aufzuhören und das Linken zu einem ausführbaren Programm gar nicht erst zu versuchen, verwenden Sie die Option -c.

Besteht der Quelltext Ihres Programms beispielsweise aus den Dateien datei1. Diese hatte ich Ihnen auf Seite schon mal vorgestellt. Steht der Dateiname in normalen Anführungzeichen, so wird nach der Header-Datei zusätzlich im aktuellen Verzeichnis gesucht.

Gelegentlich werden Sie für die Übersetzung aber auch Header-Dateien benötigen, die weder in den Systemverzeichnissen noch im aktuellen Verzeichnis stehen. Dann können Sie zusätzlich Verzeichnisse angeben, in denen der Compiler nach Headern suchen soll.

Dabei können Sie relative Pfade etwa -I.. Der Linker, der die einzelnen Objektdateien zu einem ausführbaren Programm zusammenfügen soll, verbindet die Aufrufe mit den eigentlichen Funktionen auf Ebene der Maschinensprache. Damit er die Bibliotheksfunktion dabei findet, müssen Sie beim Linken noch die entsprechende Bibliothek dazubinden. Dazu haben Sie zwei Möglichkeiten: Diese arbeitet ganz analog zu der für Include-Dateien. Die Option -L wirkt dabei indes nur auf die -l -Befehle, die Sie danach angeben.

Somit sollten Sie stets zunächst die Suchpfade und dann die Binde-Kommandos schreiben. Der Linker sucht sich dabei alle Symbole heraus, die im restlichen Programm zwar verwendet, aber nicht definiert werden.

Auch dabei ist die Reihenfolge entscheidend. Optimierung Normalerweise versucht der Compiler, die ihm gestellte Aufgabe, also das Übersetzen eines Programms, möglichst schnell zu erledigen. Das ist während des Entwicklungszyklus sicherlich auch für den Programmierer hilfreich. Ist das Programm dann aber einmal fertig und soll seine Arbeit verrichten, so sind Sie vermutlich daran interessiert, dass es diese so schnell wie möglich vollbringt.

Dafür schalten Sie die Optimierung ein. Compiler-Optimierung ist ein eigenes wissenschaftliches Fachgebiet.

Der GCC war lange Zeit dafür bekannt, dass er besser optimiert als viele seiner kommerziellen Konkurrenten. Unter Linux liegt er immer noch in der Spitzengruppe. In älteren Programmierbüchern können Sie oft lesen, wie man Code schreiben sollte, damit er vom Compiler optimal umgesetzt werden kann.

Aufgrund der Fähigkeiten des automatischen Optimierers können Sie sich diese Feinheiten heute sparen. Natürlich sollten Sie immer noch Ihre Algorithmen möglichst ökonomisch organisieren -- aber die Beachtung von bestimmten Reihenfolgen von Anweisungen oder Befehle, um Variablen in die Prozessorregister unterzubringen, sind nicht mehr nötig.

Sie müssen nicht einmal wissen, was der Optimierer eigentlich macht, denn Sie interessiert es ja nur, dass Ihr Programm möglichst schnell läuft. Die Standardoption zum Einschalten der Optimierung ist -O. Es gibt dazu sogar noch Steigerungen: Mit -O2 und -O3 schalten Sie noch zusätzliche Optimierungsverfahren dazu. Zuweilen kann das aber des Guten zu viel werden, denn manche Programme zeigen bei zu hohem Optimierungsniveau ein unvorhersagbares Verhalten bis hin zu Abstürzen. Daher ist das einfache -O meist die Methode der Wahl.

Ein so optimiertes Programm läuft natürlich auf Rechnern mit Prozessoren der vorhergehenden Generationen nicht mehr. Dazu geben Sie einfach ein: Eine wesentliche Vereinfachung der Bedienung können Sie schon mit xinfo erreichen.

Dann erhalten Sie die Informationen wenigstens in einem X-Window und können etwas mit der Maus klicken. Dort müssen Sie nur nach dem Stichwort gcc suchen und dieses anklicken.

Dann sollten Sie die in Abbildung dargestellte Seite vor sich sehen. Editieren mit NEdit Vielleicht hatten Sie während des Lesens ab und zu schon den Wunsch, auch ein kleines Programm zu schreiben und zu übersetzen. Ich habe schon viel über Programmierung erzählt, aber noch nichts, wie man den Quelltext eigentlich eintippt. Entsprechend vielseitig ist die Palette der Bedienphilosophien. Viele Editoren sind meiner Erfahrung nach für Anfänger ungeeignet, da dabei sehr eigenwillige Tastenkombinationen nötig sind.

Und da ich davon ausgehe, dass Sie vor Ihrer Beschäftigung mit Linux schon einige Erfahrungen mit Windows oder MacOS gemacht haben, möchte ich Sie lieber auf Werkzeuge hinweisen, deren Handhabung Ihnen etwas vertrauter vorkommen müsste. Es macht doch keinen Sinn, wenn Sie sich nicht nur in eine neue Programmiersprache, sondern gleichzeitig auch in einen ungewohnten Texteditor einarbeiten müssten, oder? Später ab Seite will ich Ihnen noch einige Editoren im Detail vorstellen sowie verschiedene integrierte Entwicklungsumgebungen besprechen.

Damit nicht alles aus dem Zusammenhang gerissen wird, Sie aber jetzt schon Ihre ersten Programme schreiben können, möchte ich an dieser Stelle einen Editor herausgreifen und Ihnen ein paar Tipps zur Arbeit mit NEdit geben. Er lehnt sich insbesondere an die unter Windows und MacOS verwendeten Konventionen an und bietet zum Beispiel Menüs, Dialogfenster, Bearbeitungsmöglichkeiten mit der Maus sowie die gewohnten Shortcuts.

Viele Distributionen beinhalten bereits NEdit. Natürlich können Sie sich auch mit der neuesten Version aus dem Internet versorgen; dort gibt es sogar schon vorkompilierte Versionen. Sehen Sie dazu am besten auf der Homepage www.

Die Bedienung erfolgt in gewohnter Weise. Ein sehr hilfreiches Feature ist das Syntax-Highlighting , das die verschiedenen Sprachelemente wie Schlüsselwörter, Präprozessordirektiven oder Kommentare in Farbe und Schrifttyp voneinander abhebt. Das Programm erkennt an der Dateierweiterung. Entsprechend sind Einrückungen und Ähnliches automatisch eingestellt, so dass Sie immer einen Block auch in derselben Spalte beginnen können.

Wenn Sie an die Stelle hinter einer Klammer kommen, wird die zugehörige Klammer kurz durch ein rotes Quadrat markiert. Wenn Sie also einmal einen Sachverhalt nicht als selbsterklärend erachten, finden Sie dort sicherlich Rat. Und nun kann ich Ihnen nur raten, die gezeigten Beispiel immer wieder zu laden, zu verändern und zu erweitern -- und natürlich auch eigene Programme zu schreiben.

Sicher werden Sie dabei immer wieder mit den verschiedensten Fehlermeldungen des Compilers konfrontiert werden. Aber nur auf diese Weise werden Sie mit der Zeit seine Arbeitsweise verstehen und zu einem korrekten Programmierstil gelangen, mit dem Sie Ihre eigentlichen Aufgaben angehen können.

Zusammenfassung Die wichtigsten Aspekte dieses Abschnitts waren: Als Argument erwartet dieser zumindest den Namen der Quelltext-Datei. Die Option -g bewirkt, dass Informationen für den Debugger hinzugefügt werden. Was ist an folgendem Aufruf falsch? Klassen und Objekte Auf den Seiten ff. Klassendeklaration und -definition Eine Klasse ist zunächst einmal ein von Ihnen definierter Datentyp.

Sie müssen sie deklarieren, damit sie dem Compiler bekannt ist. Eine Klasse hat im Allgemeinen folgende Bestandteile: Zugriffsbeschränkungen für ihre Elemente: Diese legen fest, ob andere Klassen auf ein Element dieser Klasse zugreifen dürfen oder nicht siehe Seite. Diese Funktionen werden aufgerufen, wenn ein Objekt dieser Klasse erzeugt beziehungsweise vernichtet wird.

Durch einen Konstruktor kann beispielsweise Speicherplatz für das Objekt bereitgestellt und es selbst initialisiert werden. Hier sind die eigentlichen Daten gespeichert. Attribute werden wie Variablen deklariert. Sie können bei jedem Objekt andere Werte haben.

Attribute können einen Standarddatentyp haben oder selbst wieder ein Objekt einer anderen Klasse sein. Methoden können auf die Attribute und Zustände des Objekts zugreifen. Deklaration Die Syntax zur Klassendeklaration besteht aus dem Schlüsselwort class , dann dem Namen der Klasse, gefolgt von den Klassenbestandteilen; diese sind von geschweiften Klammern eingeschlossen.

Kommen wir auf unser Beispiel von Seite zurück. Neu ist der Typ string ; dies ist eine Klasse für Zeichenketten, die wir später noch öfter verwenden werden. In den Zeilen 13 und 14 stehen die Deklarationen des Konstruktors und des Destruktors. Dies sind Funktionen, die immer dann automatisch aufgerufen werden, wenn ein Objekt von dieser Klasse erzeugt beziehungsweise vernichtet wird. Aber dazu in einem der nächsten Abschnitte mehr. Definition und Bereichsoperator Wahrscheinlich ist Ihnen nach dieser Überschrift nicht ganz klar, was jetzt schon wieder auf Sie zukommt.

Was ist denn der Unterschied zwischen Deklaration und Definition einer Klasse? Man macht ihn hauptsächlich an den Methoden fest: Eine Deklaration dient dazu, den neuen Datentyp dem Compiler bekannt zu machen. Dabei müssen Sie die Typen aller Attribute sowie die Schnittstellen Köpfe der Methoden angeben, also auch welche Parameter eine Methode benötigt und von welchem Datentyp der Rückgabewert ist.

Wie die Methoden implementiert sind, müssen Sie hier noch nicht angeben. Kurz gefasst bedeutet dies: Auf diese Weise können Sie ein Stück Prozessabstraktion verwirklichen: Andere, die Ihre Klasse verwenden wollen, müssen nur die Header-Datei, also die Deklaration kennen; die Definition kann im Verborgenen bleiben.

Wie wir später sehen werden, ist die Realität leider etwas komplizierter. Es ist nämlich auch erlaubt, die Definition einer Methode gleich inmitten der Klassendeklaration zu schreiben. Im Augenblick können Sie aber bei dieser Trennung bleiben. Dazu verwenden Sie den Bereichsoperator:: Später Seite werden wir die Möglichkeiten der Positionen, an denen Sie Deklaration und Definition unterbringen können, noch genauer fassen.

Ist sie erst einmal definiert, gilt sie als Datentyp. Wir können sie dann wie jeden anderen Datentyp verwenden und Variablen davon bilden. Man spricht bei einer Variablen, die als Typ eine Klasse hat, von einem Objekt dieser Klasse oder auch von einer Instanz der Klasse auch wenn das eine nicht ganz korrekte Übersetzung des englischen Begriffs instance ist.

Zugriffsbeschränkungen Zugriffsbeschränkungen regeln, ob andere Klassen auf ein Klassenelement zugreifen dürfen oder nicht. Dabei gibt es folgende Möglichkeiten: Die nachfolgenden Elemente und Methoden unterliegen keiner Zugriffsbeschränkung, sie können daher beliebig verändert beziehungsweise aufgerufen werden.

Es gibt auch noch eine dritte Ebene, protected , die wir aber erst später -- ab Seite -- behandeln wollen. Wenn Sie eine Zugriffsbeschränkung angeben, gilt diese für alle nachfolgenden Elemente -- solange, bis eine andere Beschränkung kommt oder die Klassendeklaration endet.

Fehlt in einer Klasse die Festlegung der Zugriffsbeschränkung ganz, so werden alle Elemente als private behandelt. In obigem Beispiel haben wir die beiden Zugriffsebenen in folgender Form verwendet: Wenn Sie in Ihrem Programm etwa die Anweisung schreiben: Anders sieht es in den Methoden der Klasse selbst aus. Hier dürfen Sie stets auf alle Elemente zugreifen, natürlich auch auf die privaten.

Betrachten Sie folgende Methode: Die Zugriffsbeschränkung gilt auf der Ebene der Klassen und nicht der Objekte. Wenn in einer Methode ein Objekt derselben Klasse auftaucht, so hat die Methode Zugang zu allen Elementen des Objekts, öffentliche wie private, zum Lesen wie zum Schreiben. Freunde Wenn Sie einmal in die Lage geraten, dass Sie ohne die Zugriffsmöglichkeit auf private Elemente einer anderen Klasse nicht weiterkommen, deutet das meistens auf einen Designfehler hin.

Allerdings gibt es in der Praxis durchaus Fälle, bei denen ein Verzicht auf den Zugriff einen sehr viel umständlicheren und damit meist langsameren Code mit sich bringen würde.

Damit teilen Sie dem Compiler innerhalb der Klassendeklaration mit, welche anderen Elemente vollen Zugriff auf die Klasse erhalten. Funktionen einzelne Methoden anderer Klassen ganze Klassen Im Englischen packt man diese Eigenschaft in ein leicht zweideutiges Wortspiel: Only friends may touch your private things. Dieses Vorrecht räumer wir damit aber nur der B:: Andere Methoden von B sofern vorhanden haben kein Zugriffsrecht auf A:: Zudem haben wir in einer erneuten Vorwärts-Deklaration auf eine Klasse C hingewiesen, die an anderer Stelle deklariert werden kann, die aber hier das volle Zugriffsrecht auf A erhalten hat.

Zusammenfassung Aus diesem Abschnitt sollten Sie sich merken: Klassen haben folgende Merkmale: Um eine Methode als zu einer bestimmten Klasse zugehörig zu kennzeichnen, verwendet man den Bereichsoperator:: Ist eine Klasse einmal definiert, kann sie wie jeder andere Datentyp verwendet werden.

Zugriffsbeschränkungen regeln, ob andere Klassen auf ein Klassenelement zugreifen dürfen oder nicht. Alle auf public folgenden Elemente unterliegen keiner Zugriffsbeschränkung, während alle unter private nur innerhalb der Klasse selbst zugänglich sind. Das Schlüsselwort friend erlaubt es Funktionen, einzelnen Methoden anderer Klassen oder sogar ganzen Klassen, die Zugriffsbeschränkungen zu umgehen.

Beachten Sie dabei die Zugriffsbeschränkungen und die erforderlichen Methoden. Was versteht man unter einer Vorwärts-Deklaration? Wozu wird sie benötigt? Die Möglichkeit, Funktionen zu bilden, ist ein herausragendes Merkmal einer Programmiersprache. Ganz allgemein versteht man unter einer Funktion einen in sich geschlossenen Programmteil, der eine bestimmte Aufgabe erfüllt. Eine Funktion, die zu einer Klasse gehört, nennt man Methode.

Betrachten wir folgendes Beispiel: Vorher noch ein typografischer Hinweis: Es hat sich eingebürgert, in Büchern zwei Klammern hinter Bezeichner zu setzen, die sich auf eine Funktion beziehen, zum Beispiel in Sätzen wie: Mit add erreichen Sie die Addition zweier Ganzzahlen. Das sagt noch nichts über Art und Umfang der Argumentliste aus, sondern soll Sie lediglich daran erinnern, dass es dabei um eine Funktion und nicht um eine Variable geht. Ich will mich auch in diesem Buch daran halten.

Manchmal ist es aber auch gar nicht nötig oder sinnvoll, dass eine Funktion überhaupt einen Rückgabewert hat. In diesem Fall geben Sie als Typ void an. Was macht man nun mit einem solchen Wert? Der Programmteil, der die Funktion aufruft, kann diese an allen Stellen einsetzen, wo er sonst eine Variable oder Konstante angeben würde in obiger Form allerdings nur dort, wo lediglich der Wert benötigt wird , also etwa: Selbst wenn eine Funktion einen Wert zurückgibt, müssen Sie ihn nicht beachten.

Sie dürfen auch schreiben: Argumentliste Eine Funktion kann immer nur auf den Daten arbeiten, die ihr lokal vorliegen. Von diesen Parametern auch Argumente genannt können Sie keinen, einen oder mehrere angeben, die Sie dann durch Kommas trennen. Wenn Sie eine Funktion ohne Argumente schreiben wollen, lassen Sie den Bereich zwischen den beiden runden Klammern einfach leer -- denn die Klammern müssen Sie stets schreiben!

Ansonsten geben Sie für jeden Parameter seinen Datentyp und einen Namen an, unter dem er in der Funktion bekannt sein soll. Dieser Name kann vollkommen anders sein, als der im Hauptprogramm beim Aufruf verwendete. Funktionskörper Hier stehen die Anweisungen, die bei einem Aufruf der Funktion ausgeführt werden. Man kann darüber streiten, wie lang Funktionen sein sollten. Es gibt Experten, die fordern, dass eine Funktion aus nicht mehr als 50 Zeilen bestehen dürfe, sonst werde sie unleserlich.

Es gibt jedoch in der Praxis immer wieder Fälle, in denen längere Funktionen sinnvoll sind. Bei der objektorientierten Programmierung werden Sie allerdings ohnehin wesentlich mehr Funktionen beziehungsweise Methoden verwenden, die im Durchschnitt wesentlich kürzer sind als bei der prozeduralen Programmierung.

Innerhalb des Funktionskörpers können Sie die Funktionsparameter wie normale Variablen verwenden; zusätzlich können Sie natürlich auch noch lokale Variablen definieren.

Sie dürfen sogar die Funktion selbst wieder aufrufen; man spricht dann von einer rekursiven Funktion -- aber das ist ein eigenes Thema. Return-Anweisung Die Anweisungen im Funktionskörper werden so lange abgearbeitet, bis das Programm auf das Ende der Funktion oder eine return -Anweisung trifft. Diese erfüllt einen doppelten Zweck: Sie legen fest, welchen Wert die Funktion an das Hauptprogramm zurückliefern soll.

Das kann eine Variable sein oder ein Ausdruck, eine Konstante oder der Rückgabewert einer anderen Funktion wobei Letzteres als schlechter Stil gilt. Der Typ des angegebenen Werts muss jedoch in jedem Fall mit dem deklarierten Rückgabetyp übereinstimmen. Sie beenden die Funktion und kehren zum Hauptprogramm zurück. Jede return -Anweisung -- sei sie nun am Ende oder irgendwo inmitten des Funktionskörpers -- markiert das Ende der Abarbeitung der Funktion und den Rücksprung an die Stelle, von der aus die Funktion aufgerufen wurde.

Sie können also die Funktion schon beenden, bevor alle Anweisungen ausgeführt sind, zum Beispiel wenn eine bestimmte Bedingung erfüllt ist. Ist der Rückgabetyp void , muss am Ende der Funktion keine return -Anweisung stehen auch nicht das Schlüsselwort return , wie in folgendem Beispiel: Der Prototyp Bevor Sie eine Funktion verwenden können, müssen Sie dem Compiler zunächst mitteilen, dass es eine Funktion dieses Namens gibt, wie viele und welche Parameter sie hat und welchen Typ sie zurückliefert.

Dies geschieht mit einem so genannten Prototyp der Funktion. Der Prototyp sieht genauso aus wie die Funktion selbst bis auf den Funktionskörper; dieser fehlt und wird durch ein einfaches Semikolon ; ersetzt. Es ist sogar erlaubt, die Namen der Argumente wegzulassen und nur ihre Typen anzugeben. Folgendes Beispiel zeigt den Umgang mit Prototypen: In main werden sie dann aufgerufen Zeilen und ab Zeile 17 definiert. Wenn das Programm aber weiter wächst, kann der Verlass auf die Reihenfolge schnell zu Problemen führen.

Am besten verwenden Sie für jede Quelltextdatei eine eigene Header-Datei. Hier ist dies haupt. Gegenüber dem obigen Code müssen Sie bei der Implementierung in getrennten Dateien dort noch einen include -Befehl für die Header-Datei mit den Funktionsprototypen einfügen, also: Beides zusammen bezeichnet man gelegentlich auch als Signatur der Funktion.

Damit erhalten Sie die Freiheit, zwei Funktionen gleichen Namens zu verwenden, die sich aber in ihren Argumenten unterscheiden. Man bezeichnet das auch als Überladung des Funktionsnamens. Wir hatten oben Seite eine Funktion add definiert, um zwei Ganzzahlen zu addieren. Nun kann man natürlich auch Dezimalbrüche addieren; das deckt unsere Funktion aber nicht ab.

Wir definieren also eine zweite Funktion mit demselben Namen! Gerade wenn zwei Funktionen wie unsere beiden add dieselbe Anzahl von Argumenten haben und zudem nur Standardtypen verwenden, ist es für den Compiler machmal schwer, eindeutig die passende Funktion zu einem bestimmten Aufruf zu finden. Betrachten Sie etwa folgenden Code und überlegen Sie sich vor dem Weiterlesen, welche Funktion in den jeweiligen Zeilen aufgerufen wird: Sehen wir uns die Aufrufe also genauer an: Bei den Zeilen 8 und 9 ist alles klar: Hier werden nur double - beziehungsweise int -Werte als Parameter übergeben, so dass die jeweiligen Funktionen aufgerufen werden.

In Zeile 10 ist das zweite Argument ein 'a' , also vom Typ char. Dieser Typ zählt auch zu den Ganzzahl-Werten und kann nach int konvertiert werden. Es kommt also die int,int -Variante zum Einsatz. In Zeile 11 kommt es zum Streitfall: Zum einen könnte die Zahl 3. Was soll der Compiler also tun? Da er ratlos ist, gibt er eine Fehlermeldung aus: Hier müssen wir als Programmierer eingreifen. Eine Lösung sehen Sie in Zeile Durch die explizite Umwandlung von c nach float wird die Eindeutigkeit wiederhergestellt.

Ein ganz ähnliches Problem findet sich auch in Zeile Sie sehen daran, dass es im Grunde keinen Unterschied macht, ob Sie echte Zahlen als Argumente einsetzen im Fachjargon literale Konstanten oder Variablen.

Die Möglichkeiten zur impliziten Konvertierung und damit zum Auftreten von Doppeldeutigkeiten sind stets vorhanden. Genauso wie Funktionen können Sie auch Methoden in Klassen überladen. Folgendes Programm gibt die übergebenen Argumente auf den Bildschirm aus: Die for -Schleife in Zeile 7, zu deren Syntax wir später noch genauer kommen Seite , durchläuft einfach alle Argumente vom ersten bis zum letzten, wie in argc angegeben.

Wenn Sie sehr umfangreiche Listen von Kommandozeilenargumenten verarbeiten wollen, empfehle ich Ihnen den Einsatz der Bibliotheksroutine getopt , die ich Ihnen auf Seite vorstellen werde. Schauen wir uns ein Beispiel an: Die Funktion printNumber kann mit einem, mit zwei oder mit drei Parametern aufgerufen werden, jedoch nur in der angegebenen Reihenfolge.

Somit sind folgende drei Aufrufe identisch: Alle Parameter mit Vorgabewerten müssen am Ende der Argumentliste stehen. Es darf also nach ihnen kein Argument ohne Vorgabewert folgen.

Beim Aufruf müssen Sie ebenfalls die Reihenfolge der Parameter beachten. Bei mehreren Argumenten mit Vorgabewert bedeutet das, dass Sie nicht willkürlich mal ein Argument angeben, beim nächsten aber auf den Vorgabewert vertrauen dürfen.

Bei obigem Beispiel müssen Sie also immer, wenn Sie fillchar setzen wollen, auch fillsize setzen. Es ist Ihnen sicher jetzt schon klar, dass Vorgabewerte für Parameter zuweilen recht praktisch sein können. Hat etwa eine Funktion oder eine Methode! Aber auch aus Sicht der etwas abstrakteren Objektorientierung sind Vorgabewerte willkommen -- denn sie sorgen für Erweiterbarkeit. Nun kommen Sie in die Situation, ein weiteres Argument zu der Funktion hinzufügen zu müssen.

In einer Programmiersprache ohne die Möglichkeit von Vorgabewerten müssten Sie nun an allen Stellen, an denen updateDisplay aufgerufen wird, Ihr Programm ändern und einen Standardwert hinzufügen. Neu zu schreibende Aufrufe können indessen den zusätzlichen Parameter nutzen.

Sie können damit ein und denselben Speicherplatz unter zwei verschiedenen Namen im Programm ansprechen. Jede Modifikation der Referenz ist eine Modifikation der Variablen selbst -- und umgekehrt. Wenn Ihnen das jetzt etwas abstrakt vorkommt, befinden Sie sich in guter Gesellschaft. Daher gleich ein Beispiel: Wenn Sie ihn an anderer Stelle verwenden, hat er leider eine völlig andere Bedeutung.

Eine Referenz muss stets bei ihrer Deklaration sofort initialisiert werden. Es ist also nicht möglich, eine Referenz erst einmal zu deklarieren, um ihr dann später etwas zuzuweisen. Eine Referenz einer Variable kann später nicht auf eine andere Variable umgesetzt werden. Falls Sie also einen Aliasnamen für verschiedene Variablen hintereinander benötigen, müssen Sie jeweils eine eigene Referenz verwenden.

Der Datentyp der Referenz und der Variablen müssen übereinstimmen. Selbst wenn zwei Typen durch implizite Konvertierung ineinander umgewandelt werden können, ist es nicht zulässig, eine Referenz mit einer Variablen eines anderen Typs zu initialisieren.

Innerhalb einer Funktion verwendet man nicht allzu häufig Referenzen. Manchmal kommt man aber zu ziemlich langen Ausdrücken, insbesondere bei Objekten, deren Attribute wieder Objekte sind und so weiter; dann kann der Einsatz von Referenzen für solche verschachtelten Attribute die Lesbarkeit deutlich erhöhen.

Die häufigste Anwendung ist aber die Übergabe von Funktionsparametern als Referenz, wie wir sie im nächsten Abschnitt kennen lernen werden. Parameterübergabe als Referenz Bisher waren wir davon ausgegangen, dass eine Funktion die Parameter, die sie erhält, nur verwendet -- also liest -- und nicht verändert.

In einigen Fällen aber will man gerade, dass die Funktion die Parameter verändert. Hat die Funktion beispielsweise mehrere Ergebniswerte, so reicht der eine return -Wert zum Austausch der Information nicht aus.

Sehen wir uns etwa folgende Funktion an: Die Antwort ist leider nein. Es findet zwar ein Austausch statt, aber das Hauptprogramm erfährt davon nichts. Die Variablen, die dieser Funktion übergeben werden, haben hinterher immer noch dieselben Inhalte wie vorher. Ganz anders sieht die Lage aus, wenn die Parameter als Referenzen übergeben werden auf Englisch call by reference genannt.

Dann sind diese nämlich nicht im Unterprogramm eigenständige Speicherstellen, die nach dem Rücksprung wieder freigegeben werden, sondern Aliasnamen für die Variablen im Hauptprogramm. Jede Änderung, die das Unterprogramm, also die Funktion, an den Parametern vornimmt, wirkt unmittelbar auf die im Hauptprogramm definierten und der Funktion übergebenen Variablen. Um das zu erreichen, müssen wir obige Funktion nur ein klein wenig abändern: Konstanten und Referenzen Wenn Sie einer Funktion ein Objekt per Wert übergeben im Fachenglisch call by value genannt , wird eine Kopie des Objekts angelegt, mit dem die Funktion dann arbeitet.

Daher wäre es besser, diese als Referenz zu übergeben, denn dabei bekommt die Funktion nur den Verweis auf die Speicherstelle, was sehr schnell und einfach abgewickelt werden kann. Das Problem dabei ist jedoch, dass damit der Funktion das Recht eingeräumt wird, das Objekt in jeder beliebigen Form zu verändern, was ja meist nicht beabsichtigt ist. Um dieses Problem in den Griff zu bekommen, verwenden Sie das Schlüsselwort const. Damit können Sie jede Variable und jede Referenz als konstant deklarieren, so dass sie nicht mehr verändert werden kann.

Wenn Sie also in Ihrem Programm einen bestimmten Wert mehrfach benötigen, sollten Sie ihn an zentraler Stelle zum Beispiel global in der Hauptdatei des Projekts oder in einer entsprechenden Header-Datei als Konstante definieren und später dann nur noch diesen Namen für den entsprechenden Wert verwenden. Ein Vorteil dabei ist, dass Sie später, wenn Sie das Programm mit einem anderen Wert übersetzen wollen, diesen nur einmal ändern müssen und ihn im Allgemeinen auch sofort finden.

Was hilft uns das Schlüsselwort const beim Problem der Parameterübergabe? Sie bauen die Funktion so, dass sie nicht eine einfache Referenz als Argument erhält, sondern eine konstante Referenz. Dann hat sie beispielsweise folgende Form: Am Aufruf sieht man nicht, ob da ein Objekt, eine Referenz oder eine konstante Referenz übergeben wird. Vielleicht ist Ihnen aufgefallen, dass ich die ganze Zeit von Objekten gesprochen habe, während vorher immer allgemeiner von Variablen die Rede war.

Der Grund dafür ist, dass konstante Referenzen im Allgemeinen nur für Objekte benutzt werden. Konstante Methoden Obwohl es eigentlich nichts mit Referenzen zu tun hat, wollen wir uns kurz noch mit dem Thema Konstante Methoden beschäftigen. Nachdem Sie jetzt wissen, wie Sie einer Funktion ein konstantes Objekt übergeben, ist Ihnen vermutlich noch nicht so ganz klar, was Sie in der Funktion mit dem Objekt machen dürfen und was nicht. Und wenn es Ihnen schon nicht klar ist, werden Sie es dem Compiler sicher ebenfalls kaum begreiflich machen können.

Die Attribute dürfen bei einem konstanten Objekt nur gelesen, aber nicht überschrieben werden. Was ist aber mit den Methoden? Wenn Sie eine Methode eines Objekts aufrufen, wissen Sie ja nicht, was darin genau passiert. Möglicherweise finden darin ja Modifikationen an den Attributen statt -- genau das, was wir mit dem konstanten Objekt ja verhindern wollten.

Ich kann Sie beruhigen: Solche Methoden darf die Funktion nicht aufrufen, das verhindert bereits der Compiler. Hier kommt das Schlüsselwort const abermals zum Einsatz. Damit eine Methode für ein konstantes Objekt aufgerufen werden darf, müssen Sie diese in der Klasse als const deklarieren. Dieses const muss nach der Argumentliste und vor dem Semikolon beziehungsweise dem Methodenkörper stehen.

Wenn Deklaration und Definition einer Methode getrennt sind, muss const bei beiden stehen, sonst fasst der Compiler die Definition als eine andere Signatur auf. Sehen wir uns das an einem Beispiel an: Fragen Sie sich besser bei jeder Methode, ob diese eine Veränderung des Objekts bewirken soll oder nicht; im letzteren Fall deklarieren Sie sie stets als const. Somit werden Sie übrigens auch daran gehindert, die stets fehlerträchtigen Nebeneffekte zu programmieren -- schon mancher Benutzer einer Klasse hat sich gewundert, warum sein Objekt nach einem Lesezugriff plötzlich verändert war.

Zugriffsroutinen Sie erinnern sich sicherlich, dass ich Ihnen die Datenabstraktion als wichtiges Prinzip der objektorientierten Programmierung vorgestellt habe auf Seite. Schlagen Sie am besten nochmals Abbildung 2. Dort wird gezeigt, dass im Idealfall andere Objekte nur über Nachrichten auf die Daten eines Objekts zugreifen können. Nachrichten werden aber als Methoden des Empfängers implementiert. Für die Datenelemente Ihrer Klasse empfiehlt sich folgende Vorgehensweise: Deklarieren Sie alle Datenelemente als private und nur Methoden als public.

Um den Bezug zum Attribut herzustellen sowie gleichzeitig die Bedeutung zu illustrieren, verwenden viele Programmierer auch ich für die Namen dieser Methoden immer die Vorsilben get beziehungsweise set , gefolgt vom Namen des Attributs. Deklarieren Sie alle Lesemethoden als const. In unserer Beispielklasse haben Sie bereits solche Methoden gesehen: Inline-Funktionen Was passiert eigentlich bei einem Funktions- oder Methodenaufruf?

Grob gesprochen wird der Programmfluss angehalten, die Parameter in einen speziellen Bereich genannt Stack kopiert, der Ausgangspunkt gemerkt und an den Beginn der Funktion gesprungen. Nach deren Abarbeitung werden ihre lokalen Variablen wieder gelöscht, der Stack aufgeräumt und das Hauptprogramm fortgesetzt.

Bei sehr kurzen Funktionen, wie sie bei der objektorientierten Programmierung häufiger als anderswo auftauchen zum Beispiel als Zugriffsmethoden , dauert die Verwaltung des Aufrufs länger als die Abarbeitung selbst.

Abhilfe bieten da so genannte inline -Funktionen. Durch die Angabe dieses Schlüsselworts vor einer Funktion erreichen Sie, dass für die Funktion kein Aufruf im oben genannten Sinn erzeugt wird, sondern der Funktionskörper direkt an die Stelle eingefügt wird eben in line, in der Zeile. Es ist dann also keine echte Funktion mehr, sondern nur ein Stück Code im Hauptprogramm. Erfahrenen C-Programmierern kommt jetzt sicher der Gedanke an Makros.

Auch diese bewirken eine Ersetzung schon durch den Präprozessor ; allerdings können bei diesen keine Datentypen für die Argumente definiert werden. Bei inline -Funktionen bleibt die Prüfung des Argumenttyps sowie der sonstigen Syntax genauso erhalten, als ob es sich um eine tatsächliche Funktion handeln würde.

Deklaration als inline Um eine Funktion als inline zu deklarieren, schreiben Sie dieses Schlüsselwort zur Definition, und zwar als Allererstes, also noch vor den Rückgabetyp, zum Beispiel: Sie können die Behandlung einer Funktion als inline nicht erzwingen.

Allgemein sollten Sie komplexere Funktionen, die eine Reihe von Anweisungen sowie Schleifen und Ähnliches enthalten, nicht als inline deklarieren. Selbst wenn der Compiler dies akzeptiert und umsetzt, besteht dadurch die Gefahr, dass Ihr Code stark aufgebläht und die Optimierung behindert wird. Die Implementation einer als inline deklarierten Funktion sollte immer in einer Header-Datei stehen.

Wenn Sie nämlich im Header den Prototyp angeben und erst in der Implementationsdatei die Funktion als inline kennzeichnen, wird bei der Verwendung in anderen Dateien jeweils ein normaler Aufruf erzeugt, was spätestens beim Linken zu Problemen führt.

Klassenmethoden als inline Zugriffsmethoden von Klassen sind die idealen Kandidaten für die inline -Deklaration. Sie sind meist sehr kurz, werden aber ziemlich oft benötigt. Mit dem jetzigen Wissen können Sie sich auch für eine andere Stelle entscheiden, an der Sie Ihre Methode implementieren. Deklaration und Definition innerhalb der Klassendeklaration. Wenn Sie eine Methode direkt innerhalb der Klassendeklaration implementieren, also auch den Funktionskörper angeben, wird diese automatisch als inline behandelt, auch wenn das entsprechende Schlüsselwort fehlt.

Das ist bei sehr kurzen Methoden ein oder zwei Zeilen durchaus üblich. Deklaration und Definition als inline -Funktion in der Header-Datei. Wenn Sie Ihre Methode als inline gelten lassen wollen, sollten Sie sie aus oben beschriebenen Gründen innerhalb der Header-Datei implementieren.

Diese Möglichkeit wählt man oft bei etwas längeren Methoden mit mehr als zwei Zeilen , die aber noch sehr einfach sind, also beispielsweise keine Schleifen enthalten, oder wenn man auf Klassenelemente zugreifen muss, die erst später deklariert werden.

Deklaration in der Header-Datei und Definition in der Implementationsdatei. Jede davon wird dann als echte Funktion behandelt, die einmal zu Objektcode übersetzt und später dann nur noch dazugelinkt werden muss. Sehen wir uns die drei Varianten in der Praxis an. Die erste Möglichkeit führt etwa zu folgendem Code: Die zweite Variante hat beispielsweise folgende Form: Anders sieht dies beim dritten Fall aus.

Hier findet sich im Include-File nur noch: Zusammenfassung In diesem Abschnitt haben Sie eine Menge gelernt.

Die wichtigsten Aspekte waren: Funktionen liefern immer einen Wert zurück, es sei denn, die Funktion ist als void definiert. Eine Funktion kann einen oder mehrere Parameter haben. Jede Funktion muss vor ihrer Verwendung deklariert werden: Sie ist der Einstiegspunkt in das Programm. Der Rückgabewert von main kann von der Shell, die das Programm startet, ausgewertet werden. Daher können Sie zwei Funktionen gleichen Namens mit unterschiedlichen Argumenten definieren überladene Funktionen.

Sie können für einzelne Argumente einer Funktion Vorgabewerte engl. Eine Referenz ist ein Aliasname für eine Variable. Jede Modifikation der Referenz führt zu einer Modifikation der Variablen und umgekehrt. Übergibt man einer Funktion eine Referenz, so kann diese den Inhalt der übergebenen Variablen ändern. Um zu vermeiden, dass der gesamte Datenbestand eines Objekts bei einem Funktionsaufruf kopiert wird, und um zu verhindern, dass die Funktion den Inhalt des Objekts ändern kann, übergibt man eine konstante Referenz auf das Objekt an die Funktion.

Ist eine Funktion oder Methode als inline deklariert, wird bei der Kompilierung der Aufruf vollständig durch den Funktionskörper ersetzt. Das bietet sich besonders bei Zugriffsmethoden auf Klassenelemente an.

Übungsaufgaben Beantworten Sie folgende Fragen: Wie viele Rückgabewerte kann eine Funktion haben? Was ist die Signatur einer Funktion? Kann eine Klasse zwei Methoden gleichen Namens enthalten, die sich nur in ihren Rückgabewerten unterscheiden? Was stimmt bei folgendem Programm nicht: Eine rationale Zahl wird dargestellt durch mit ganzzahligen und , wobei. Addition und Multiplikation sind wie bekannt definiert.

Schreiben Sie eine Klasse Rational , die eine rationale Zahl repräsentiert. Diese soll über die Rechenfunktionen add , sub , mult und div verfügen, wobei der Bruch stets vollständig gekürzt gespeichert werden soll. Die Klasse habe folgende Struktur: Konstruktoren und Destruktoren Wenn Sie bereits mit anderen Programmiersprachen gearbeitet haben, wird Ihnen das Konzept der Konstruktoren und Destruktoren zunächst etwas merkwürdig vorkommen -- handelt es sich doch um Funktionen, die aufgerufen werden, ohne dass ihr Aufruf im Programmtext steht!

Mit der Zeit werden Sie aber die Abläufe verstehen und merken, dass auch da kein Geheimnis dahinter steckt. Besondere Eigenschaften Konstruktoren haben einige besondere Eigenschaften, die sie von allen anderen Methoden unterscheiden: Aufrufe von Konstruktoren werden automatisch in das Programm eingefügt.

Jedes Mal, wenn ein Objekt erzeugt wird und die Klasse über einen entsprechenden Konstruktor verfügt, wird dieser aufgerufen. Explizite Konstruktoraufrufe gibt es also nicht.

Konstruktoren tragen denselben Namen wie die Klasse. Alle anderen Namen können keine Konstruktoren bezeichnen. Konstruktoren haben keine Rückgabewerte auch nicht void. Sie dürfen keinen Rückgabetyp bei der Deklaration eines Konstruktors angeben und auch keine void -Anweisungen mit Argument verwenden.

Ein einfaches, schon klassisches Beispiel für einen selbst definierten Datentyp ist ein Datum , das einen Tag im Kalender repräsentiert. Ich will in diesem Abschnitt eine solche Klasse mit Ihnen aufbauen, um die verschiedenen Arten von Konstruktoren deutlich zu machen. Standardkonstruktor englisch default constructor.

Dieser wird bei jeder Erzeugung eines Objekts der Klasse verwendet, wenn kein anderer Konstruktor in Frage kommt. Dieser kann beliebige Argumente haben und wie eine Methode überladen werden. Es können also mehrere Konstruktoren mit verschiedenen Argumentlisten existieren. Auch Vorgabewerte für die Argumente sind erlaubt. Dieser dient dazu, ein Objekt dieser Klasse mit einem anderen derselben Klasse zu initialisieren. Er erhält dazu als Argument eine konstante Referenz auf das Objekt. Dieser hat nur ein Argument und dient dazu, einen anderen Datentyp in die Klasse als Typ gesehen umzuwandeln.

Im Folgenden wollen wir die verschiedenen Konstruktoren genauer betrachten. Standardkonstruktor Der Standardkonstruktor, der leider viel zu oft auch im Deutschen mit dem englischen Ausdruck default constructor bezeichnet wird, hat keine Argumente. Er wird immer dann aufgerufen, wenn ein Objekt dieser Klasse ohne weitere Angaben erzeugt wird. Bei unserem Beispiel lautet die Deklaration: Ich sprach oben davon, dass eine der Aufgaben des Konstruktors sei, Speicherplatz für die Attribute bereitzustellen.

Vielleicht fragen Sie sich nun, warum Sie davon in dieser Methode nichts sehen. Ebenso wie bei lokalen Variablen -- unabhängig davon, ob ihr Typ einfach oder eine Klasse ist -- kann das System selbstständig ermitteln, wie viel Speicher die Attribute benötigen, und diesen entsprechend reservieren.

Auch das kann innerhalb eines Konstruktors geschehen. Doch dazu kommen wir später noch. Jetzt sehen wir uns an, wo der Konstruktor aufgerufen wird. In einem Hauptprogramm steht beispielsweise: Natürlich können Sie auch mit der Klasse arbeiten und Objekte davon erzeugen, wenn diese keinen Konstruktor hat. Allerdings sind dann die Attribute in einem unbestimmten Zustand -- genauso wie Variablen, die Sie nur deklariert, aber nicht initialisiert haben. Ich möchte Ihnen daher empfehlen, bei allen Ihren Objekten zumindest einen Standardkonstruktor zu definieren.

Da er beispielsweise keinen Rückgabewert hat, werden mögliche Fehler nicht ohne Weiteres vom Programm bemerkt. Richten Sie im Zweifelsfall lieber eine zusätzliche Methode ein, in der dann kritische Initialisierungen vorgenommen werden können.

Hintergrund Die Einfügung des Konstruktoraufrufs klappt übrigens auch bei Verschachtelungen. Lyme, Spirochetes, Flagyl and the Nitroimidazoles: Über die Wirkung von F. Bei einer Bakterienpopulation variiert die Einzelzell-Generationsdauer während der Entwicklung der Population. Man unterscheidet die folgenden Entwicklungsphasen Stephen T. In der Literatur werden zu einzelnen Antibiotika die Absterbekinetiken von Borrelia burgdorferi berichtet. Konsequenzen für die Therapie? Jahrgang, Heft 5, Hier ist das Argument dafür: Prinzipiell kann die Abtötung gleich schnell 1.

Es ergibt sich damit eine Bb-Generationsdauer von weniger als den genannten Das ist in Übereinstimmung mit Züchtungsexperimenten von z. Wenn das Zellwandantibiotikum bei einer Teilung einer Zelle den Zelltod dieser Zelle plus den Tod anderer Zellen herbeiführt, verläuft mit Antibiotikum die Abtötung schneller als die Zellteilung in Abwesenheit des Antibiotikums: A mathematical model for the efficacy and toxicity of aminoglycoside April Pharmacokinetic-Pharmacodynamic Modeling of activity of ceftazidime during continuous and intermittent infusion.

Antimicrobial Agents and Chemotherapy ;1 4: Einige Grundlagen zur diesen Überlegungen zugrundeliegenden Pharmakodynamik. Entscheidend dafür ist der MHC major histocompatibility complex. Die Gliazellen sind im Gegensatz zu den Nervenzellen vermehrungsfähig. Spirochäten, also auch Borrelia burgdorferi , sind gramnegativ. Die beta-Lactam-Antibiotika überwinden einige beta-Lactamasen grampositiver Bakterien, gegen die restlichen sind sie wirkungslos.

Es gibt keine graduellen Aktivitätsabstufungen der beta-Lactam-Antibiotika, die von ihrer Konzentration oder Einwirkungsdauer abhinge. Im Gegensatz dazu steigt ihre Wirkung auf gram-negative Bakterien mit der Einwirkungsdauer und Konzentration kinetisch behinderte Wirkung: Sie ist schwächer ist als bei gram-positiven Bakterien.

Unter dem Selektionsdruck potenter moderner beta-Lactam-Antibiotika entwickeln sich jedoch neue Stämme Mutanten mit effizienterer Barriere. Guillain-Barre-Syndrom auch Radikularneuritis genannt , eine meist infektiöse Poly neuritis. GBS ist eine akut-entzündliche Myelin-Verlust verursachende demyelinisierende Krankheit, welche die peripheren Nerven befällt.

Dies ist in guter Näherung bei intravenöser Infusion der Fall. Das Antibiotikum wird auf dem Weg a, z. Die Ausscheidung auf dem Weg a aus dem Körperkompartment K beschreibt man mithilfe der fogenden Differentialgleichung: Zur Bedeutung von k: Dividiert man beide Seiten von Gl.

Der Vorteil der Beschreibung Gl. Verteilungsvolumen für ein spezifiziertes Kompartment K, z. Unter Verwendung von V erhält man für die Halbwertszeit aus Gl. Beispiele für V Clearance für einen spezifizierten Ausscheideweg a und ein spezifiziertes Kompartment K: Darin kürzt man den Ausdruck k V mit CL, der sog. Zur Bedeutung von CL siehe auch Clearance: Weil V das Verteilungsvolumen des Kompartments K z.

Materialsammlung in der Newsgroup sci. Die Haplotypen werden ererbt. Zur Abhängigkeit bei Borreliose: Hsp werden aber auch in einem weiten Spektrum von Bakterien und Parasiten erzeugt. Das würde eine Autoimmun-Komponente bei diesen Infektionen zur Folge haben d. Weitere Beispiele aus der Borreliose-spezifischen Literatur: Alaedini A, Latov N. Epub Nov Sequence homology between spirochete flagellin and human myelin basic protein.

Molecular mimicry in Lyme disease: Biochim Biophys Acta, ; Von aktivierten T-Zellen erzeugt das Immunsystem sog. Über ein diesbezügliches Borreliose-spezifisches Forschungsprojekt unter der Leitung von Adriana Marques wurde am Die T-Zellen antworteten am stärksten auf B. J Autoimmun May;16 3: Identification of candidate T-cell epitopes and molecular mimics in chronic Lyme disease , Nat Med Dec;5 Molekulare Mimicry - Einige Gedanken und Anregungen für eine Medline-Suche Molecular mimicry as a possible mechanism of disease in chronic Lyme disease is being revealed more and more.

Recent studies demonstrate significant homologies between Borrelia components and thyroid system or cardiac muscle host tissues at the molecular level. Thus an auto-immune attack may occur by mistake and contribute to disease pathology or even be a mechanism adapted by parasites to downregulate needed host defenses. In general these studies do not address the persistence of Borrelia as a persistent stimulus to host autoimmune dysfunctions. Clinicians treating chronic Lyme with chronic antibiotics often find that initial autoimmune markers found associated with Lyme Disease patients decrease in titer and then disappear along with the clinical evidence of persistent illness.

This is found, for example, in positive ANA titers, positive Rheumatoid factor levels, positive anti thyroglobulin levels, positive anti cardiolipin levels etc. This is so common that if a battery inclusive of a wide range of "auto antibodies" were done on every chronic Lyme Disease patient, then a heterogeneous but everpresent display of molecular mimicry would be expected. The decrease and then disappearance of these markers with antibiotic treatment is evidence that the continued immune dysfunction of self attack is dependent not only on continued near homologies with the germs but also with the continued presence of the microbes- even though the germ load at later stages of treatment may be more at a smoldering infection of little fires in niche tissue sites ie similar to persistent vaccination.

Our immune system has evolved so advanced in recognizing self from dangers of pathogens that it may not be likely that the switch is turned on so absolutely by pathogen mimicry that is not absolute.

Can patented pharmaceuticals be so discrete as to target the immune mimicry switches without impairing essential other host immune messages and messengers? Or would it be better to follow the path of microbe eradication and downregulation of host immune dysfunction as a natural course?

Jüngste Studien zeigen bedeutsame Ähnlichkeiten sog. Homologien zwischen Borrelien-Komponenten und Schilddrüsensystem- oder Herzmuskel-Wirtsgewebe auf der molekularen Ebene. Daher kann ein Autoimmunangriff als Fehler auftreten und zum Krankheitsverlauf beitragen oder sogar ein Mechanismus sein, den Parasiten anpassen, um notwendige Wirtsabwehr herunterzuschrauben "herabzuregeln".

Allgemein sprechen diese Studien das Überleben von Borrelien nicht an, den nicht abklingenden persistenten Auslöser Stimulus der Wirts-Fehlfunktionen. Man findet das z. Können patentierte Pharmazeutika so genau auf die Immun-Mimicry-Schalter gezielt wirken, ohne unabdingbare andere Immunmeldungen und -Melder des Wirts zu beeinträächtigen? Wir finden die möglichen dosisabhängigen Retinaschädigungen und irreversiblen Hörschäden der Bedenken wert.

Retinaschäden verschlimmerten sich auch nach Absetzen von Chloroquin weiter: Hilfreich sind auch dieselben Suchbegriffe in Verbindung mit chloroquine statt hydroxychloroquine. Um diesen vorzubeugen, nimmt man es oft mit Diazepan Benzodiazepin, einem Beruhigungsmittel , ein. Auch besondere Gefahr des Überwuchern durch Hefen.

Die so entstandenen Komplexe, also in unserem Beispiel die Antiköper: Immunglobuline sind für jedes Antigen spezifisch, es gibt also z. Wenn IgM innerhalb von 30 Tagen nach einem dokumentierten Zeckenstich auftritt. The seroprevalence of Borrelia IgG antibodies was 3. In addition, another 55 children reported a history of LB but were negative to Borrelia IgG antibodies in serum. Time course of development of antibodies and appearance of antigen entnommen aus IgeneX-Papier: Clinical characterisitics of 39 culture-positive patients with EM.

About one-quarter of the patients remembered a tick bite at the site where an expanding erythema was noted a median of 9 days later. The study physicians evaluated the patients a median of 4 days range, 1 to 21 days after the onset of EM.

Associated symptoms included malaise and fatigue, fever and chills, headache and neck stiffness, and arthralgias. All of the patients had the resolution of EM and associated symptoms within a median duration of 6 days after the start of antibiotic therapy. Kuby, lymphocyte activation , acute inflammatory response: Immune cells first encounter B. EM lesions have mild-to-marked perivascular infiltrates of T cells and macrophages and, sometimes, small numbers of plasma cells As a part of the innate immune response, spirochetal lipoproteins bind the CD14 molecule and toll-like receptor 2 on macrophages in EM lesions, which leads to the production of proinflammatory cytokines To initiate an adaptive immune response, antigen presenting cells, including macrophages and dendritic cells, engulf spirochetes 13 and migrate via afferent lymphatics to peripheral lymph nodes where they present processed spirochetal peptides to T cells.

Some spirochetes in EM lesions may express small amounts of OspA, and the presentation of small amounts of processed OspA peptides in regional lymph nodes may be enough to trigger a T-cell response. A single major histocompatibility peptide complex can trigger serially up to T-cell receptors 31 , and optimal T-cell stimulation may be achieved by interaction with as few as 1, T-cell receptors as long as costimulatory molecules are also engaged 31 , Borrelia-specific B cells are activated by intact B.

In contrast with the small amounts of peptides required to activate T cells, the amount of antigen required for activation of an individual B cell is variable and depends on B-cell receptor affinity 2.

Therefore, in most cases, the amounts of intact OspA draining to lymph nodes must be insufficient to cross-link immunoglobulin on the surface of B cells, and therefore, B cells are not activated.

Affinity dependence of the B cell response to antigen: Human dendritic cells process and phagocytose Borrelia burgdorferi. Inflammatory signaling by Borrelia burgdorferi lipoproteins is mediated by toll-like receptor 2. Differential expression of cytokine mRNA in skin specimens from patients with erythema migrans or acrodermatitis chronica atrophicans.

Serial triggering of many T-cell receptors by a few peptide-MHC complexes. T cell activation determined by T cell receptor number and tunable thresholds. Wirkung auf die Entwicklung der Krankheit J. Diese Antikörper scheinen keine Schutzwirkung zu haben, sondern im Gegenteil sogar zur Krankheitsentstehung beitzutragen.

Sie können das Komplement-System Kapitel 14 von J. Andererseits führen Spaltprodukte von Komplementsystem -Komponenten, z. Obwohl das Auftrennen von Komplexen vor dem quantitativen Nachweis wissenschaftlicher Standard in z.

Ann Neurol Dec;28 6: Schutzer steht , trennen die gebräuchlichen medizinischen diagnostischen Tests bis heute Stand: Die on-line-Version der Deutschen Ärztezeitung bezeichnete am Eine site-spezifische Suche nach "Schutzer" oder "Coyle", den Wissenschaftlern, welche die Komplexauftrennung in die Borreliosediagnostik einführten, oder nach "Borreliose" und "Immunkomplex" oder "Auftrennen" ergab dort keine Treffer.

Immunsystem "The immune system is divided into a more primitive innate immune system, and acquired or adaptive immune system of vertebrates, each of which contains humoral and cellular components. Kuby, Immunology 3rd edition , Chapter 1 Überblick im Cache. Entzündungsantwort im Cache - bei Borreliose Humorale und zell-vermittelte Antwort im Cache , siehe auch in dieser Datei unter Lymphozyten.

Wechselwirkung der Zellen des Immunsystems bei der Immunabwehr im Cache. Zellen des Immunsystems im Cache. Wechselwirkungen zwischen Immunsystem, endokrinem System und Zentralnervensystem bei Borreliose. Die fluorchromierten Moleküle werden unter dem Mikroskop gesucht. In dieser Zeit treten die Borreliose-Symptome nach M.

Barkley, meist gehäuft und stärker auf Marylynn S. Impfung gegen Lyme-Borreliose ist noch in der Entwicklung. Humoral immunity has been shown to play a role in protection and this has spurred efforts towards developing a Lyme disease vaccine.

A number of protective immunogens have been characterised to date, but due to the heterogeneity of Lyme disease Borreliae, no single molecule has proven to be completely effective as a vaccinogen. This review will describe the immunogens that have been used to protect against B.

In addition, the promising aspects and the limitations of each protective immunogen will be discussed. Exner, M , Successful vaccination for Lyme disease: Expert Opin Biol Ther Sep;1 5: Ein Cephalosporin der 2. Sie können auf einem Transposon kodiert vorliegen, das die beta-Lactamase-Produktion auf andere Bakterien übertragen kann, die zuvor nicht beta-lactam-aktiv waren.

Die Entwicklung dieser Stämme ist reversibel, d. Plasmid -kodierte oder auch als "Plasmid-vermittelt" bezeichnete beta-Lactamasen, z. Diese Art der beta-Lactasmase-Produktion kann auf andere Bakterien übergehen, die vorher nicht beta-lactam-aktiv waren. Für eine Dauerinfusion , d. Es gibt eine unauffällige, elektronisch gesteuerte Pumpe Infusionspumpe, engl.

Intrakompartment-Antikörper-Synthese , auf Englisch intracompartmental antibody synthesis, oder z. Der Labornachweis für B. Intrathekale Antikörper-Produktion oder -Synthese ist eine hinreichende, aber nicht notwendige Bedingung für Neuroborreliose, d.

Klinische Diagnostische Techniken , Patricia K. Coyle in Brian A. Weitere Informationen zu "antigenic variation" siehe Indest, KA, et al. Sie sind mit bio- oder immunchemischen Methoden voneinander trennbar. Notwendigkeit der Behandlungsfortsetzung bei J-H-R. Ursprünglich hielt man freigesetztes Toxin Endotoxin für verantwortlich. Blood lactic acid is increased. The cardiac output remains high, indicating hypotension resulting from low systemic vascular resistance, at the same time pulmonary arterial pressure is increased.

The administration of pure oxygen does not alter the changes in ventilation and circulation but favorably influences lactic acidosis. This may be a sign of tissue hypoxia. The lack of a favorable effect of hydrocortisone that acts as a stabilizer is also of interest. During recovery from the reaction, the mean pressure in the brachial artery remains low but cardiac output is still increased.

Weitere Literatur kan man mit einer Medlne -Suche nach den Stichworten "Parry tetracycline relapsing" finden. Wenn nichts anderes in Frage kommt, tippt man auf Lyme. In einer bedeutsamen Arbeit stellt die Mikrobiologin D. Honegr K, Hulinska D, et al. Persistence of Borrelia burgdorferi sensu lato in patients with Lyme borreliosis , Epidemiol Mikrobiol Imunol. Nach seiner Aktivierung entstehen in einer stark kontrollierten enzymatischen Kaskade Komplement-Komponenten C1 - C4, deren Wechselwirkung zur Bildung von Reaktionsprodukten führt, die die Entzündung und Antigen-Beseitigung bewirken.

Kuby , Immunology Chapter The Complement System "The complement system, the major effector of the humoral branch of the immune system, consists of nearly 30 serum and membrane proteins.

Following initial activation, the various complement components interact, in a highly regulated enzymatic cascade, to generate reaction products that facilitate antigen clearance and generation of an inflammatory response.

There are two pathways of complement activation: The complement reaction products amplify the initial antigen-antibody reaction and convert that reaction into a more effective defense mechanism. A variety of small, diffusible reation products that are released during complement activation induce localized vasodilatation and attract phagocytic cells chemotactically, leading to an inflammatory reaction.

As antigen becomes coated with complement reaction products, it is more readily phagocytosed by phagocytic cells that bear receptors for these complement products.

In addition, some of the complement products have been shown to play a role in the activation of B lymphocytes. Finally, the terminal components of the complement system generate the membrane-attack complex. Chapter 14 describes the similarities and differences in the two pahtways, the regulation of the complement system, the effector functions of various complement components, and the consequences of ereditary deficiencies in some components.

Kortison wird zur Behandlung endzündlich-allergischer Zustände eingesetzt, es setzt die Immunreaktion des Körpers herab. Oft bei endzündlichen Vorgängen eingesetztes Präparat, das die Heilungschancen der Borreliose verringert siehe auch John Drulle Antibiotika und Steroide. Sie gelangen in den Zellkern und wirken von dort steuernd auf eine reduzierte T-Zell -Aktivierung und Zytokin-Erzeugung hin. Verringerung der phag ozytischen Eigenschaften von Makrophagen und Neutrophilen , chemotaktischen Anziehung von entzündungsspezifischen Zellen.

Kuby , Seite Borrelien oder Zellen auf einem Nährsubstrat, auf das Körperzellen, z. Serum oder Liquor , aufgebracht wurden.

Schwierigkeiten bei der Kultur von Borrelia burgdorferi. L-Formen von Bb vermehren sich nicht auf kommerziell erhältlichen Nährsubstraten. Solche Kulturen sind falsch negativ.

Man züchtet daher zunächst aus den L-Formen die spirochetale Normal- Form zurück und vermehrt diese dann. Dazu ist ein passendes Kulturmedium erforderlich Phillips et al. Uta Everth , sehr sorgfältige Arbeiten gemacht, u. Grundprinzipien der Therapie mit Arzneimitteln", newlife-online.