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
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