24.08.2013 Aufrufe

001-Folien: Los geht's: C++ um komplexe Zahlen erweitern

001-Folien: Los geht's: C++ um komplexe Zahlen erweitern

001-Folien: Los geht's: C++ um komplexe Zahlen erweitern

MEHR ANZEIGEN
WENIGER ANZEIGEN

Sie wollen auch ein ePaper? Erhöhen Sie die Reichweite Ihrer Titel.

YUMPU macht aus Druck-PDFs automatisch weboptimierte ePaper, die Google liebt.

VL MRT-2<br />

Algorithmen und<br />

Datenstrukturen in <strong>C++</strong><br />

VL MRT-2, SS 2013<br />

Professur für Prozessleittechnik


Übersicht<br />

• Erste Schritte mit Eclipse/CDT<br />

– Wie lege ich ein <strong>C++</strong> Projekt an?<br />

– Wie übersetze und starte ich ein Programm?<br />

• Unser erstes <strong>C++</strong> Programm<br />

– Rechnen mit <strong>komplexe</strong>n <strong>Zahlen</strong><br />

– Wie definiere ich eine neue Objektklasse?<br />

– Wie definiere ich Attribute und Methoden?<br />

– Wie nutze ich das nahtlos in meinem Programm?<br />

08.04.2013 MRT2 (c) 2013, UR<br />

Folie 2


Ziel: Frequenzgangs eines Filter berechnen<br />

• Implementierung als <strong>C++</strong>-Programm?<br />

double R = 1000, C = 1E-6, w;<br />

complex c, j(0,1);<br />

for (w=1; w


<strong>Los</strong> geht‘s: Hello World in <strong>C++</strong><br />

• Integrierte Entwicklungs<strong>um</strong>gebung<br />

– Virtuelle Maschine mit der Applicance starten<br />

– Eclipse/CDT starten<br />

– ggf. neuen Workspace anlegen:<br />

File Switch Workspace Other...<br />

• <strong>C++</strong> Projekt anlegen<br />

– File New <strong>C++</strong> Projekt<br />

– Project Name: ComplexN<strong>um</strong>bers<br />

Schriftart für die<br />

Bedienung von<br />

Eclipse-Menus<br />

– ProjectType: Executable / Hello World <strong>C++</strong> Projekt<br />

08.04.2013 MRT2 (c) 2013, UR Folie 4


Eclipse/CDT IDE<br />

Projektansicht<br />

mit Verzeichnis<br />

Editor<br />

Konsolenausgabe<br />

Schnellzugriff<br />

für Ausführen,<br />

Debuggen<br />

Wechsel der<br />

Perspektive<br />

Struktur der<br />

Datei im Editor<br />

08.04.2013 MRT2 (c) 2013, UR Folie 5


ComplexN<strong>um</strong>bers.cpp – bekanntes von C<br />

//====== [...]<br />

#include <br />

using namespace std;<br />

int main() {<br />

}<br />

cout


Build & Run<br />

• Build All (Strg+B)<br />

– Übersetzt und bindet alle offenen Projektdateien<br />

– Erzeugt lauffähige Programme<br />

– Alternative: Project Build All<br />

– Ausgabe in View Console (CDT Build Console)<br />

• Run (Strg+F11)<br />

– Startet das Programm des aktuellen Projekts<br />

– Alterantive: Run Run As Local C/<strong>C++</strong> Application<br />

– Ausgabe in View Console (CDT Build Console)<br />

08.04.2013 MRT2 (c) 2013, UR Folie 7


Zwei erste <strong>C++</strong> Konzepte<br />

//====== [...]<br />

#include <br />

using namespace std;<br />

int main() {<br />

}<br />

cout


<strong>C++</strong> Konzept Namensra<strong>um</strong><br />

• Problem C: Ein Name einer Methode kann nur einmal<br />

verwendet werden Namenskonflikte<br />

• Lösungsansatz <strong>C++</strong>: Strukturierung durch<br />

hierarchische Namensrä<strong>um</strong>e - Meier aus Dresden<br />

– Spezifikation eines Symbols aus einem Namensra<strong>um</strong>s<br />

durch Angabe des vollständigen Namen mit<br />

Namensra<strong>um</strong>operator :: namespace::methode<br />

• Komfortfunktion<br />

– Vorauswahl von Namensrä<strong>um</strong>en<br />

– using namespace namespace;<br />

• Standard Bibliotheksfunktionen<br />

– Namensra<strong>um</strong> std<br />

08.04.2013 MRT2 (c) 2013, UR Folie 9


<strong>C++</strong> Konzept Strom<br />

• Ein Strom verarbeitet Sequenzen von<br />

Zeichen<br />

– Ein/Ausgabe auf Konsole: std::cout, std::cin<br />

– Bidirektional (Datei, Zeichenkette)<br />

• Ausgabeoperator


Komplexe <strong>Zahlen</strong><br />

• Definition<br />

– c = a + b i; a,b und i²=-1<br />

• Grundlegende Rechenoperationen<br />

– c 1+c 2 = (a 1+a 2) + (b 1+b 2)i<br />

– c 1-c 2 = (a 1-a 2) + (b 1-b 2)i<br />

– c 1*c 2 = (a 1a 2-b 1b 2) + (a 1b 2+b 1a 2)i<br />

– c 1/c 2 = (a 1a 2+b 1b 2)/(a 2²+ b 2²)+((a 1b 2-b 1a 2)<br />

/(a 2²+ b 2²))i<br />

08.04.2013 MRT2 (c) 2013, UR Folie 11


Abbildung in eine <strong>C++</strong> Klasse<br />

• Abstrakter Datentyp mit Attributen a,b <br />

• Operatoren +, -, *, /<br />

• Auswahl Real und Imaginärteil<br />

• Ausgabeoperator


Anlegen einer neuen Klasse<br />

• Im Kontextmenu des Projektba<strong>um</strong>s new class<br />

– Class name: complex<br />

– Kein Destruktor<br />

– Es werden zwei Dateien erzeugt<br />

• Header complex.h<br />

– Deklaration der Klasse<br />

– Methoden<br />

– Attribute<br />

• Implementierung complex.cpp<br />

– Implementierung der Algorithmen<br />

08.04.2013 MRT2 (c) 2013, UR Folie 13


complex.h - Gerüst<br />

class complex {<br />

public:<br />

};<br />

complex();<br />

<strong>C++</strong> Konzept:<br />

Klasse<br />

<strong>C++</strong> Konzept:<br />

Zugriffsmoderator<br />

<strong>C++</strong> Konzept:<br />

Konstruktor<br />

08.04.2013 MRT2 (c) 2013, UR Folie 14


Attribute, Zugriffsmethoden und<br />

Konstruktoren<br />

• Private Attribute<br />

– double real;<br />

– double imag;<br />

• Öffentliche Zugriffsmethoden<br />

– double Re();<br />

– double Im();<br />

• Öffentlicher Konstruktor mit Defaultwerten<br />

– complex(double r = 0.0, double i = 0.0);<br />

08.04.2013 MRT2 (c) 2013, UR Folie 15


Deklaration in<br />

Complex.h<br />

class complex {<br />

private:<br />

double real;<br />

double imag;<br />

public:<br />

};<br />

// Konstruktoren<br />

complex(double r = 0.0, double i = 0.0);<br />

// Zugriff auf die Attribute<br />

double Re();<br />

double Im();<br />

Zugriffsmoderator<br />

gilt bis z<strong>um</strong><br />

nächsten. Default ist<br />

protected<br />

Parameter mit<br />

default-werten sind<br />

optional.<br />

Einschränkung:<br />

kein Default in der<br />

Mitte, nur vom<br />

rechten Ende her!<br />

08.04.2013 MRT2 (c) 2013, UR Folie 16


Implementierung in<br />

Complex.cpp<br />

#include "complex.h"<br />

complex::complex(double r, double i) :<br />

}<br />

real(r), imag(i) {<br />

double complex::Re() {<br />

}<br />

return real;<br />

double complex::Im() {<br />

}<br />

return imag;<br />

Import der<br />

Prototypen<br />

Zuordnung z<strong>um</strong><br />

Namensra<strong>um</strong> der<br />

Klasse Complex<br />

Elementinitialisierungsliste<br />

mit Kopier-<br />

Konstruktoren<br />

08.04.2013 MRT2 (c) 2013, UR Folie 17


Anwendung<br />

int main() {<br />

}<br />

complex c0(1,2), c1, c2(c0);<br />

cout


Ausgabe von Klassen auf Strom<br />

• Wie sieht eine Methode aus, die das gleiche<br />

Ergebnis liefert, aber eleganter in der<br />

Anwendung ist: cout


<strong>C++</strong> Konzept: operator<br />

• Häufig Ausdrucksmuster der Art:<br />

– Ergebnis = LinkerOperand Operator<br />

RechterOperand;<br />

– Arithmetik, Logik, ...<br />

• Lösungsansatz in C oder Java:<br />

– Ergebnis = Methode(Operand1, Operand2)<br />

– Methodennamen beginnen mit [_A-Za-z]<br />

• <strong>C++</strong>: Überschreiben von Operatoren<br />

– Ergebnis = operatorXX(Operand1, Operand2)<br />

– XX ist das symbolische Kürzel des Operators<br />

08.04.2013 MRT2 (c) 2013, UR Folie 20


complex.h - Entwurf operator


Ziel: Frequenzgang eines Filters berechnen<br />

double R, C, w;<br />

complex c, j;<br />

c = ( R / R + 1 / ( j * w * C ) );<br />

• Definition<br />

– a,b,d ; i²=-1; c = a + b i;<br />

• Arithmetik<br />

– c 1+c 2 = (a 1+a 2) + (b 1+b 2)i<br />

– c 1-c 2 = (a 1-a 2) + (b 1-b 2)i<br />

– c 1*c 2 = (a 1a 2-b 1b 2) + (a 1b 2+b 1a 2)i<br />

– c 1/c 2 = (a 1a 2+b 1b 2)/(a 2²+ b 2²)+((a 1b 2-b 1a 2) /(a 2²+<br />

b 2²))i<br />

double / complex<br />

complex * double<br />

08.04.2013 MRT2 (c) 2013, UR Folie 22


Ausflug: Überladen von Operatoren in <strong>C++</strong><br />

• Fast alle Operatoren sind überladbar:<br />

• Nicht überladen werden können<br />

:: .* . ?:<br />

• Es gibt keine neuen Operatoren<br />

08.04.2013 MRT2 (c) 2013, UR Folie 23


Regeln (1/2)<br />

• Ein überladener Operator muss mindestens<br />

einen Operanden vom Typ Klasse besitzen<br />

• Priorität, Assoziativität und Anzahl der<br />

Operanden eines Operators können nicht<br />

verändert werden<br />

– Beispiel: A == B + C;<br />

– Resultiert, unabhängig vom Typ von A,B,C und<br />

den ggf. überladenen Operatoren immer in:<br />

operator==(A, operator+(B, C));<br />

08.04.2013 MRT2 (c) 2013, UR Folie 24


Regeln (2/2)<br />

• Kurzschlusseigenschaft von logischem und<br />

(&&), logischem oder (||) bleiben nicht<br />

erhalten<br />

– Es werden immer beide Operanden ausgewertet<br />

– Reihenfolge der Auswertung ist nicht festgelegt<br />

• Reihenfolge der Auswertung für<br />

Kommaoperator ist nicht definiert<br />

08.04.2013 MRT2 (c) 2013, UR Folie 25


Operator als Elementfunktion einer Klasse<br />

• Überladene Operatoren dürfen sowohl als<br />

herkömmliche Nichtelementfunktion als auch<br />

als Elementfunktion definiert werden.<br />

• Beispiel: Binärer Operator += : c += j<br />

• Definition als Nichtelementfunktion:<br />

complex& operator+=(const complex& lhs,<br />

const complex& rhs)<br />

• Definition als Elementfunktion:<br />

complex& complex::operator+=(const complex&<br />

rhs)<br />

08.04.2013 MRT2 (c) 2013, UR Folie 26


Elementfunktion vs Nichtelementfunktion<br />

• Definition als Nichtelementfunktion:<br />

complex& operator+=(const complex& lhs,<br />

const complex& rhs)<br />

• Definition als Elementfunktion:<br />

complex& complex::operator+=(const complex&<br />

rhs)<br />

• Achtung: Bei einer Definition als<br />

Elementfunktion ist der erste Operand das<br />

Objekt, repräsentiert durch den impliziten<br />

Zeiger this.<br />

08.04.2013 MRT2 (c) 2013, UR Folie 27


Der implizite Zeiger this<br />

• Jede Elementfunktion hat einen impliziten<br />

Parameter: this<br />

• this ist ein Zeiger auf ein Objekt des<br />

Klassentyps.<br />

• this ist an das Objekt gebunden, für das die<br />

Elementfunktion aufgerufen wurde.<br />

• this wird immer dann benötigt, wenn wir uns<br />

auf das Objekt als Ganzes beziehen wollen.<br />

08.04.2013 MRT2 (c) 2013, UR Folie 28


Beispiel complex<br />

• Per Definition muss += eine Referenz (= ein<br />

Stellvertreter, gekennzeichnet durch das &)<br />

auf das Objekt zurückgeben<br />

// complex += complex<br />

complex& complex::operator+=(const<br />

complex& rhs) {<br />

real+=rhs.real; imag+=rhs.imag;<br />

return *this;<br />

}<br />

08.04.2013 MRT2 (c) 2013, UR Folie 29


Heuristiken für Operatorüberladung (1/4)<br />

• Der Compiler überlädt automatisch:<br />

– Zuweisungsoperator (=): Elementweise Zuweisung<br />

– Addressierungs- (&) und Kommaoperator (,)<br />

• Arithmetische Operatoren (+, -, *, /, …)<br />

– gemäß Häufigkeit und eindeutiger<br />

Interpretierbarkeit<br />

• Zuweisungsoperatoren (+=, -=, …)<br />

– Günstig, wenn entsprechender arithmetischer<br />

Operator definiert ist<br />

08.04.2013 MRT2 (c) 2013, UR Folie 30


Heuristiken zur Operatorüberladung (2/4)<br />

• Gleichheits- und relationale Operatoren<br />

– Wenn Schlüssel in assoziativem Container, dann<br />

mindestens <<br />

– Wenn Eintrag in sequentiellem Container, dann <<br />

und == für Algorithmen wie find (==) und sort<br />

(,>= und


Elementfkt vs. Nichtelementfkt.<br />

• Elementfunktionen müssen sein:<br />

– Zuweisung (=), Indizierung ([]), Aufruf (()) und<br />

Elementzugriffspfeil (->)<br />

• Elementfunktion sollten sein:<br />

– Operatoren die den Zustand ihres Objekts verändern<br />

oder damit eng verknüpft sind<br />

– Zuweisungsoperatoren ( += -= ), Inkrementierung<br />

(++), Dekrementierung (--), Dereferenzierung (*)<br />

• Nichtelementfunktionen sollten sein:<br />

– Symetrische Operatoren wie Arithmetik (+ - * /)<br />

Gleichheit (==), relationale (< > =) und bitweise<br />

(& | ^) Operatoren<br />

08.04.2013 MRT2 (c) 2013, UR Folie 32


Rechenoperationen<br />

• Ziel: Frequenzgang eines Filters berechnen<br />

double R, C, w;<br />

complex c, j;<br />

c = ( R / R + 1 / ( j * w * C ) );<br />

• Definition<br />

– a,b,d und i²=-1<br />

– c = a + b i;<br />

• Arithmetik<br />

– c 1+c 2 = (a 1+a 2) + (b 1+b 2)i, c 1-c 2 = (a 1-a 2) + (b 1-b 2)i<br />

– c 1*c 2 = (a 1a 2-b 1b 2) + (a 1b 2+b 1a 2)i<br />

– c 1/c 2 = (a 1a 2+b 1b 2)/(a 2²+ b 2²)+((a 1b 2-b 1a 2) /(a 2²+<br />

b 2²))i<br />

08.04.2013 MRT2 (c) 2013, UR Folie 33


complex + complex<br />

• Elementfunktion operator+=<br />

// complex += complex<br />

complex& complex::operator+=(const complex& rhs) {<br />

real+=rhs.real; imag+=rhs.imag;<br />

return *this; }<br />

• Nichtelementfunktion operator+<br />

// complex = complex + complex<br />

inline complex operator+(const complex& lhs, const<br />

complex& rhs) {<br />

}<br />

complex cret(lhs);<br />

return cret += rhs;<br />

08.04.2013 MRT2 (c) 2013, UR Folie 34


Selbstständig vervollständigen...<br />

(kontrolliertes copy , paste & modify)<br />

• EF: operator+=(const double)<br />

• NEF: operator+ (const double, const<br />

complex&)<br />

• Analog für -, * und /<br />

08.04.2013 MRT2 (c) 2013, UR Folie 35


Testen<br />

int main() {<br />

complex c(2,1);<br />

cout


Berechnung Transferfunktion<br />

complex j(0,1);<br />

double C(1e-6), R(1000);<br />

complex transfer_function(double w) {<br />

}<br />

return R / ( R + 1 / ( j * w * C ));<br />

int main() {<br />

}<br />

for (double w=1; w < 1000; w += 3 ) {<br />

complex r = transfer_function(w);<br />

cout


Anzeigen mit gnuplot<br />

• Starten des Programms von der Konsole und<br />

Umleiten der Ausgabe in eine Datei:<br />

– cd MRT2/ComplexN<strong>um</strong>bers/Debug<br />

– ./ComplexN<strong>um</strong>bers > q.q<br />

• Anzeigen der 3ten über<br />

der 2ten Spalte<br />

– gnuplot<br />

– plot 'q.q' using 2:3 with lines<br />

– exit<br />

08.04.2013 MRT2 (c) 2013, UR Folie 38

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!