Code Snipplets
Auf dieser Seite sind ein paar Code-Beispiele aus der Vorlesung gesammelt. Die Beispiele machen nichts Sinnvolles, sie sollen nur wichtige Konzepte und die Syntax zeigen.Tag 1
hello.cpp
#include <iostream> // zur Ausgabe von Streams using namespace std; int main (void) // Hauptprogramm (ohne Argumente) void kann auch weggelassen werden { //Textausgabe: float x = 0.5; int a = 10; cout << "Hallo Welt!" << endl; cout << "ein Float: " << x << endl; cout << "ein Int: " << a << endl; char richtung; cout << "In Welche Richtung wollen Sie gehen? N,S,O,W?" << endl; cin >> richtung; int schritte; cout << "Wie viele Schritte?" << endl; cin >> schritte; cout << "Gehen Sie " << schritte << " Schritte in Richtung: " << richtung << endl; // Programm beenden return 0; }
operatoren.cpp
#include <iostream> #include <bitset> int main() { float x = 5.5,y = 3.3; std::cout << "x*y = " << x*y << std::endl; bool b1 = true,b2 = false; std::cout << "b1 = " << b1 << " b2 = " << b2 << std::endl; std::cout << "b1 && b2 " << (b1 && b2) << std::endl; std::cout << "b1 || b2 " << (b1 || b2) << std::endl; int a = 0b11100011; int b = 0b00101011; std::cout << "a = 0b" << std::bitset<8>(a) << std::endl << "b = 0b" << std::bitset<8>(b) << std::endl; std::cout << "a & b = 0b" << std::bitset<8>(a&b) << std::endl; std::cout << "a | b = 0b" << std::bitset<8>(a|b) << std::endl; std::cout << "a ^ b = 0b" << std::bitset<8>(a^b) << std::endl; std::cout << "~a = 0b" << std::bitset<8>(~a) << std::endl; std::cout << "a << 1 = 0b" << std::bitset<9>(a<<1) << std::endl; return 0; }
control.cpp
#include <iostream> using namespace std; int main() { int a = 22; cout << "Hex a = 0x" << hex << a << endl; cout << "Dec a = " << dec << a << endl; int numSchritte; char c; bool exit = false; while(!exit) { cout << "Welche Richtung willst du gehen? n,s,o,w" << endl; cin >> c; cout << "Gehe Richtung "; if(c==`n`){ cout << "Norden"; }else if(c == `s`){ cout << "Süden"; }else if(c == `w`){ cout << "Westen"; }else if(c == `o`){ cout << "Osten"; }else{ exit = true; } cout << endl; cout << "Wie viele Schritte willst du gehen?" << endl; cin >> numSchritte; for(int i=0; i<numSchritte; i++){ cout << i << " " << endl; } } return 0; }
for.cpp
#include <iostream> using namespace std; int main() { double x = 2.0; for(int i=1; i<=10; i++){ x = x*x - 1.0; cout << i << ": x = " << x << endl; } int hexzahl = 0xA; for ( int bit = 0b1000; bit > 0; bit >>= 1){ std::cout << ( (hexzahl&bit)? `1` : `0`); } cout << endl; char c = `5`; cout << "Char c = " << (int)c << endl; return 0; }
struktur.cpp
#include <iostream> using namespace std; struct Point{ float x,y; }; int main() { const Point pt = {5.5, 3.3}; // zugriff mit `.` operator cout << "Point pt = " << pt.x << "/" << pt.y << endl; // Array der Größe 5 int a[5]; for(int i=0; i<5; i++){ a[i] = i*i; } for(int i=0; i<5; i++){ cout << "a[" << i << "] = " << a[i] << endl; } // Ein Array kennt seine eigene Größe // (sizeof() gibt die Größe in Bytes zurück) cout << "Size Of int = " << sizeof(int) << endl; cout << "Size Of array a = " << sizeof(a)/sizeof(int) << endl; return 0; }
Tag 2
start.cpp
#include <iostream> using namespace std; int main() { char c = 15; // um den Zahlwert, anstatt des Buchstabens ( Zeichens) in char auszugeben, // muss nach int konvertiert werden cout << "char c = " << (int)c << endl; c = 0b1101; char comp = 0b1000; // der shift Operator schiebt die 1 in comp um eine Stelle weiter // ein Rechtsschift entspricht der Division durch 2 cout << "char c hat an Stelle 3: " << ((c&comp) != 0) << endl; comp = comp>>1; // 0b0100 cout << "char c hat an Stelle 2: " << ((c&comp) != 0) << endl; comp >>= 1; //0b0010 cout << "char c hat an Stelle 1: " << ((c&comp) != 0) << endl; comp >>= 1; //0b0001 cout << "char c hat an Stelle 0: " << ((c&comp) != 0) << endl; int i=3; // hier wird einie Schleife benutzt, um alle Stellen zu vergleichen for(char comp = 0b1000; comp > 0; comp >>=1){ cout << "char c hat an Stelle "<< i << ": " << ((c&comp) != 0) << endl; i--; } return 0; }
complex.cpp
#include <iostream> using namespace std; struct MyVector{ float x; float y; float z; int dim; }; // deklaration einer Funktion: definition unten void printVector(MyVector vec1); // enum erzeugt Typ,der nur bestimmte Werte annehmen kann enum Language{Unknown=0,German=4,English=2}; int main() { MyVector vec1 = {2.0,3.0,1.0,3}; // MyVector kann mit Liste initialisiert werden printVector(vec1); Language lang = German; // mit enum kann man lesbare Typen abfragen if( lang == German){ cout << "Hallo zusammen" << endl; }else if(lang == English){ cout << "Hello together" << endl; } cout << "lang = " << lang << endl; // gibt einen Integer aus const int SIZE = 10; float arrf[SIZE]; arrf[0] = 3.3; for(int i=0; i<SIZE; i++){ arrf[i] = i*i; } for(int i=0; i<SIZE; i++){ cout << "arrf[" << i << "] = " << arrf[i] << endl; } MyVector vecArr[SIZE]; // sizeof gibt Größe in Bytes zurück cout << "Sizeof MyVector = " << sizeof(vec1) << endl; cout << "Sizeof vecArr = " << sizeof(vecArr) << endl; for(int i=0; i<SIZE; i++){ vecArr[i].x = i; vecArr[i].y = i*i; vecArr[i].z = i*i+5; vecArr[i].dim = 3; } for(int i=0; i<SIZE; i++){ printVector(vecArr[i]); } return 0; } // Definition der Funktion, muss vorher Deklariert worden sein // damit sie in main bereits bekannt ist void printVector(MyVector vec1) { cout << "Vec1 = (" << vec1.x << "/" << vec1.y << "/" << vec1.z << ")" << endl; }
chararr.cpp
#include <iostream> using namespace std; int main() { char str[] = "Hallo mein name ist Manfred"; cout << str << endl; for(int i = 0; i<sizeof(str); i++){ cout << i << " : " << (int)str[i] << endl; } return 0; }
functions.cpp
#include <iostream> #include <cmath> using namespace std; // Funktion mit Rückgabetyp, Name und Argumenten int arithMean(int a, int b) { int mean = (a+b)/2; return mean; } double geomMean(int a, int b) { double mean = sqrt(a*b); return mean; } // funktion ruft sich selbst auf : Rekursion int mult(int a, int b) { if(b==1){ // Abbruchbedingung sonst endlosrekursion return a; } return a + mult(a,b-1); } int main() { int a = 10; int b = 55; int m = arithMean(a,b); // hier wird eine Funktion benutzt cout << "Arith Mean = " << m << endl; cout << "Mult Recursiv: a*b = " << mult(a,b) << endl; // Soll der Inhalt zweier Variablen getauscht werden, // muss der Wert von a kopiert werden bevor er überschrieben wird int rem = a; a = b; b = rem; return 0; }
mainargs.cpp
#include <iostream> using namespace std; // dem Programm können ebenfalls Parameter mitgegeben werden // argc hält dabei immer die Anzahl der Argumente // argv ist ein Zeiger auf char arrays, also ein Zeiger auf // beliebig viele cstrings. // der erste Parameter argv[0] hält dabei immer den Aufruf des Programmes // z.B. "./mainargs" int main(int argc, char* argv[]) { int i = 10; // i wird in main definiert //int main (int argc, char **argv) //Aquivalent cout << "Anzahl parameter = " << argc << endl; for(int i=0; i<argc; i++){ // in der Schleife wird hier ein neues i definiert cout << "Parameter " << i << ": "; cout << argv[i] << endl; } { // so kann auch einen neuen Gültigkeitsbereich öffnen int z = 66; cout << i << endl; // die Änderungen an i in der for-Schleife i = 55; // sind hier in der main nicht sichtbar cout << i << endl; } // ende eines Gütigkeits bereichs immer mit "}" return 0; }
uebergabe.cpp
#include <iostream> using namespace std; // in einem namespace werden Variablen Namen gekapselt namespace debug{ int level; } // wert wird als Referenz auf eine Float übergeben // dadruch wirken sich Änderungen von wert auch ausserhalb // der Funktion auf die Variable (hier x) aus. float mult(float & wert, int anzahl) { wert = 7.0; return wert * anzahl; } int main() { float z,x = 2.0; cout << x << endl; z = mult(x,3); // x bleibt hier 2.0 cout << x << endl; debug::level = 0; int level = 22; cout << "level = " << debug::level << endl; return 0; }
Tag 3
funktionen.cpp
#include <iostream> #include <time.h> // stellt time_t , time und difftime zur Verfügung using namespace std; // structs können auch Funktionen bekommen, diese Stehen allen // objekten dann zur Verfügung struct MyVector{ void print() const{ cout << "(" << x << "/" << y << "/" << z << ")" << endl; } void print(int dim) const{ cout << "Dim = " << dim << "(" << x << "/" << y << "/" << z << ")" << endl; } // operatoren können überladen werden // hier bekommt unsere struct einen plus Operator MyVector operator+(MyVector vec2){ MyVector newVec; newVec.x = x+vec2.x; newVec.y = y+vec2.y; newVec.z = z+vec2.z; return newVec; } float x,y,z; }; // ein Großes Array von MyVec struct MyVecArr{ MyVector arr[500000]; }; // greife auf ein Großes Objekt zu void printBig(const MyVecArr & big){ cout << "big.arr[0] = "; big.arr[0].print(); } int main() { MyVector vec1 = {1.1,22,4}; MyVector vec2 = {1.0,1.0,1.0}; vec1.print(); vec2.print(); MyVector vec3 = vec1 + vec2; vec3.print(); /* MyVecArr big; cout << "Size of big = " << sizeof(big) << endl; big.arr[0].x = 22; big.arr[0].y = 21; big.arr[0].z = 20; */ time_t start = time(NULL); // hier wird der Startzeitpunkt für unsere Zeitmessung // fest gelegt // Wird big als Referenz und nicht als Value an printBig übergeben // wird das Programm deutlich schneller ausgeführt MyVecArr big; for(int i=0; i<10000; i++){ big.arr[0].x = i; big.arr[0].y = 21; big.arr[0].z = 20; printBig(big); } // difftime gibt die Zeit zwischen end und start in Sekunden zurück time_t end = time(NULL); cout << "Vergangene Zeit = " << difftime(end,start) << " sekunden" << endl; return 0; }
zeiger.cpp
#include <iostream> #include <unistd.h> using namespace std; // hier wird ein Zeiger auf ein Feld und die Größe des Feldes übergeben void printArr0(int * arrAlt, int size){ for(int i=0; i<size; i++){ cout << "arrAlt["<<i<<"] = " << arrAlt[i] << endl; } cout << "Size of arrAlt = " << sizeof(arrAlt) << endl; } // Zeiger Können auch zurück gegeben werden // hier ist auch der Typ wichtig: Zeiger auf int (int*) int* generateArr() { const int num = 100000000; int * big = new int[num]; // wird mit new angelegt muss später mit //delete [] freigegeben werden for(int i=0; i<num; i++){ big[i] = 0; } return big; } int main() { int i = 5; cout << " i = " << i << endl; cout << "Adrese von i = " << &i << endl; int *ptr = &i; // adresse kan einem pointer zugewiesen werden cout << "ptr = " << ptr << endl; *ptr = 10; // ptr wird dereferenziert und Stelle wird mit 10 überschrieben cout << " i = " << i << endl; ptr = new int; // hier wird die Adresse eines neuen Objekts zugewiesen cout << "ptr = " << ptr << endl; cout << "*ptr = " << *ptr << endl; *ptr = 5; cout << " i = " << i << endl; cout << "*ptr = " << *ptr << endl; int arrAlt[20]; arrAlt[0] = 11; printArr0(arrAlt,20); for(int i=0; i<100; i++){ int * mem = generateArr(); cout << "mem = " << mem[0] << endl; sleep(1); // ein sleep(1) hält das Programm für 1 sekunde an delete [] mem; // sleep wird duruch <unistd.h> in linux geladen } int * arr = new int[20]; arr[0] = 5; arr[10] = 50; cout << " arr[10] = " << arr[10] << endl; // zeiger plus int gibt wieder einen Zeiger // so kann man mit Zeigern auch rechnen *(arr+10) = 20; cout << " *(arr+10) = " << *(arr+10) << endl; cout << " arr[10] = " << arr[10] << endl; int * arrPtr = arr+10; *arrPtr = 22; cout << " arr[10] = " << arr[10] << endl; delete ptr; delete [] arr; ptr = NULL; arr = NULL; }
Zusatz
inout.cpp
Hier ist ein Beispiel in dem gezeigt wird, wie man ganze Zeilen von der Konsole einlesen kann, und diese in einen File mit Hilfe eines ofstreams speichern kann. Weiter wird gezeigt wie man Daten aus einem File wieder in ein Program einlesen kann und diese im Program benutzbar macht:#include <iostream> #include <fstream> /* Übersetzen mit g++ -c inout.cpp -std=c++11 Binden mit g++ -o inout inout.o Schnellbinden mit g++ -o inout inout.cpp -std=c++11 */ using namespace std; int main () { string data; // open a file in write mode. ofstream outfile; outfile.open("afile.dat"); cout << "Writing to the file" << endl; cout << "Enter your name: "; getline(cin,data); // write inputted data into the file. outfile << data << endl; cout << "Enter your age: "; cin >> data; cin.ignore(); // again write inputted data into the file. outfile << data << endl; // close the opened file. outfile.close(); // open a file in read mode. ifstream infile; infile.open("afile.dat"); cout << "Reading from the file:" << endl; infile >> data; //getline(infile,data); // write the data at the screen. cout << data << endl; // read the data as integer from the file and display it. int age; infile >> age; if( infile.fail() ){ cerr << "Error reading age " << endl; }else{ cout << age << endl; } // close the opened file. infile.close(); return 0; }
STL Container
Standard-ContainerHier werden einige sehr nützliche container Klassen der Standard Bibliothek vorgestellt. Grundzüge des c++11 Standards werden ebenfalls gezeigt:
container.cpp
#include <iostream> #include <vector> #include <array> #include <algorithm> using namespace std; // uebersetzen mit -std=c++11 // g++ -o container container.cpp -std=c++11 -Wall // templates erlauben eine Funktion für unterschiedliche Typen // zu Definieren. "Container" kann hier beim Aufruf duch unterschiedliche // container klassen ersetzt werden. template <typename Container> void printContainer(Container container) { for(const auto & elem : container){ cout << elem << "/"; } cout << endl; } // in c++11 können Große Objekte effizient als RückgabeWert // verwendet werden. Implizit wird hier ein "move()" ausgeführt // dadurch wird bei der Rückgabe keine Kopie erzeugt. vector<int> generateLargeVector() { vector<int> largeVec(1000,1); return largeVec; // in c++11 implizit: return move(largeVec); } int main() { vector<int> v1; vector<int> v2(10,5); vector<float> v3(15,5.5); //durch Anhängen von Elementenfüllen eines Vectors for(int i=0; i<6; i++){ v1.push_back(i*i+3); } printContainer< vector<int> >(v1); // Aufruf der Funktion für vector<int> printContainer< vector<int> >(v2); printContainer< vector<float> >(v3); // Aufruf der Funktion für vector<float> // stl array fester Größe cout << "Print Array: " << endl; array<int,6> arr1 {1,2,3,2,1,4}; printContainer< array<int,6> >(arr1); // auch für ein Array kann die Funktion benutzt werden // mit iteratoren kann amn genauso rechnen wie mit pointern cout << " Begin = " << *v1.begin() << endl; cout << " Begin = " << *(v1.begin()+4) << endl; cout << " End -1 = " << *(v1.end()-1) << endl; cout << " End -1 = " << v1.end()[-1] << endl; int x=5; auto a = x; // wenn Typ eindeutig ist kann in c++11 auto verwendet werden // rangebased loops mit auto // auto referenz erzeugt eine Referenz des benötigten Typs // die Referenz ist hier nötig um Änderungen in der Schleife // auch ausserhalb sichtbar zu machen. cout << "Range based loop:" << endl; for(auto & v : v1){ v+=10; cout << v << "/"; } cout << endl; printContainer< vector<int> >(v1); // initialisierung mit einer initializer list // durch weglassen von "=" vector< vector<int> > vecvec {{1,2,3,4,4},{5,4,3},{2,3,7,7,2,1,5},{4,3,2,2}}; for(auto & vec : vecvec){ sort(vec.begin(),vec.end()); // sort algorithmus der stl// printContainer<vector<int>>(vec); } return 0; }
funktionen.cpp
#include <iostream> // für die Ausgabe mit cout #include <cmath> // für die sqrt() Funktion #include <array> // für das std::array using namespace std; int gloabalX = 6; // Globale Variable struct MyVector{ float x,y,z; }; void printMyVector(const MyVector & vec); // MyVector wird an Funktion übergeben //Eine Funktion besteht aus RückgabeTyp Name (FunktionsParametern,..) double arithMean(int a, int b) { double mean = (a+b)/2.; // durch Umwandlung einer Variable in einen float wird // die ganze Operation in floats durchgeführt return mean; } double geomMittel(int a, int b) { double mean = sqrt(a*b); return mean; } // Rekursive Funktionen bruachen eine Abbruchbedinung int recursiveMult(int a, int b) { if(b==1) return a; return a + recursiveMult(a,b-1); } // Funktion ruft die print Funktion auf. // Das Übergebene Array kennt seine Größe nicht mehr // Daher muss die Größe separat übergeben werden void printVecArray(MyVector vec[], int size) { cout << sizeof(vec) << endl; for(int i=0; i<size; i++){ printMyVector(vec[i]); } } // Das std::array kennt die Größe des Arrays // Durch Übergabe einer const Referenz muss das Array nicht in // den Gültigkeitsbereich der Funktion kopiert werden // Const & gibt auch an, dass vec in der Funktion nicht verändert wird void printVecArray(const std::array<MyVector,10> & vec) { cout << sizeof(vec) << endl; cout << vec.size() << endl; for(int i=0; i<vec.size(); i++){ printMyVector(vec[i]); } } int main() { int a=5,b=6; int mean = arithMean(a,b); cout << "Arithmetisches Mittel von " << a << " und " << b << " ist " << arithMean(a,b) << endl; cout << "Geometrisches Mittel von " << a << " und " << b << " ist " << geomMittel(a,b) << endl; cout << "Recursive Mult von " << a << " und " << b << " ist " << recursiveMult(a,b) << endl; MyVector vec = {1.1,1.5,5.}; // hier funktioniert die Initialisierung mit {,,}; printMyVector(vec); MyVector vecArr[10]; for(int i=0 ; i<10; i++){ vecArr[i] = {1.1,1.5,(float)i}; //hierfür muss -std=c++11 dem Compiler mitgegeben werden } printVecArray(vecArr,10); // Das std::array benötigt den Enthaltenen Typen und die Anzahl in <,> std::array<MyVector,10> vecArray; for(int i=0 ; i<10; i++){ vecArray[i] = {1.1,1.5,(float)i}; } printVecArray(vecArray); return 0; } //Funktion wird nach main definiert benögt Deklaration vor Benutzung void printMyVector(const MyVector & vec) { // static variable wird nur beim ersten Funktionsaufruf initialisiert // static variable ist hier nur lokal innerhalb der Funktion gültig // i zählt hier die Anzahl der Funktionsaufrufe über das gesamte Programm static int i = 0; cout << "(" << vec.x; cout << "/" << vec.y; cout << "/" << vec.z; cout << ")" << i << endl; i++; }
modulo.cpp
Ein Codefragment zur Erklärung der Funktionsweise des Modulo Operators:#include <iostream> using namespace std; int main() { for(int i=0;i<20; i++){ cout.width(2); cout << i << " modulo 7 ist: " << i%7 << endl; } return 0; }
zeiger.cpp
#include <iostream> using namespace std; // mit namespaces kann man Variablen in einen speziallen Kontext setzen namespace MyDebug { int level = 2; } // eine Große Struktur struct Big{ void init(); // Strukturen können eigene Funktionen enthalten void print(){ // Kann direkt in der struktur definition definiert werden cout << "Zahl 0 = " << zahlen[0] << endl; } bool flag; float zahlen[1000]; }; // Struktur Funktionen werden im namespace der Struct Definiert void Big::init() { for(int i=0; i<1000; i++){ zahlen[i] = i*i; } } // Große Struktur wird mit einer Referenz übergeben (Änderung außen sichtbar) void setBig(Big & big ,bool flag){ big.flag = flag; } struct Point{ float left,right; }; // Übergabe von Point "per Value" void addLeftToRight(Point point) { cout << "Point l+r = " << point.left + point.right << endl; point.left = point.left + point.right; } // Übergabe von Point "per Referenz". Zugriff wie oben. void addLeftToRightRef(Point &point) { cout << "Point l+r = " << point.left + point.right << endl; point.left = point.left + point.right; } // Übergabe von Point "per Pointer" zugriff mit "->" Operator Point * addLeftToRightRef(Point *point) { cout << "Point l+r = " << point->left + point->right << endl; point->left = point->left + point->right; return point; // Zeiger können auch zurück gegeben werden } int main() { Big big; big.flag = true; cout << "Big flag is " << big.flag << endl; setBig(big,false); cout << "Big flag is " << big.flag << endl; //Änderung außen sichtbar MyDebug::level = 4; // Zugriff auf level im namespace MyDebug int level = 5; // Variable level ist noch frei im leeren namespace big.init(); // Aufruf von struct Funktionen mit "." big.print(); Big big2; big2.zahlen[0] = 10; big2.print(); big.print(); int i = 6; cout << "Adresse von i = " << &i << endl; // Adresse von i ausgeben int *iptr = &i; // iptr ist ein Zeiger auf ein int // iptr zeigt jetzt auf die Adresse von i cout << "Iptr von i = " << iptr << endl; // Wert von iptr ist Adresse von i cout << "Iptr von i = " << *iptr << endl; // Wert auf dein iptr zeigt *iptr = 5; // Den Wert auf den iptr zeigt verändern cout << "i = " << i << endl; // i hat jetzt einen anderen Wert (= 5) // Zeiger können auch für ein Array verwendet werden int *iarr = new int[10]; // Platz für 10 ints reservieren *(iarr + 6) = 16; // Mit Zeigern kann gerechnet werden es geht auch iarr[6] = 16 cout << iarr[6] << endl; // Genau wie bei Arrays gibt den int an Stelle 6 aus ( 7. Eintrag) delete [] iarr; // Speicher MUSS auch wieder freigegeben werden. WEnn bei new [] dann auch delete [] Big * bigPtr = new Big; // Zeiger auf ein neu erzeugten Struct bigPtr->flag = true; // Bei Zeigern auf Strukturen greift man mit "->" auf die Struct-Elemente zu delete bigPtr; // Struct wieder freigeben Point point; // Point als Objekt erzeugen point.left = 5; // Strukturvariablen werden mit "." gesetzt point.right = 10; addLeftToRight(point); // Objekt zu Objekt muss nichts getan werden cout << "Point left = "<<point.left<<endl; // Left = 5 addLeftToRightRef(point); // Objekt zu Referenz muss nichts getan werden cout << "Point left = "<<point.left<<endl; // Left = 15 addLeftToRightRef(&point); // Objekt zu Zeiger muss Adresse übergeben werden (mit &) cout << "Point left = "<<point.left<<endl; // Left = 25 Point *point2 = new Point; // Point als Zeiger neu erzeugen point2->left = 5; // Strukturvariablen werden mit "->" gesetzt point2->right = 10; addLeftToRight(*point2); //Zeiger zu Objekt mit Dereferenzierungsoperator * cout << "Point left = "<<point2->left<<endl;// Left = 5 addLeftToRightRef(point2); //Zeiger zu Referenz muss nichts getan werden cout << "Point left = "<<point2->left<<endl;// Left = 15 addLeftToRightRef(point2); //Zeiger zu Zeiger muss nichts getan werden cout << "Point left = "<<point2->left<<endl;// Left = 25 delete point2; return 0; }
Hier ist noch das CMake skript welches ich benutzt habe um die MyVector Klasse zu bauen. Die MYVector Klasse finden Sie in den Übungen, bzw. in den Musterlösungen.
CMakeLists.txt
cmake_minimum_required (VERSION 2.6) project (MyVector) #add all required cpp files set (MY_VECTOR_SRCS main.cpp MyVector.cpp ) # add the executable add_executable(MyVector ${MY_VECTOR_SRCS})
SimpleVector (Vererbung)
main.cpp
#include <iostream> #include "SimpleVector.h" #include "SmartVector.h" using namespace std; void printVector(SimpleVector & v) { cout << "The vector is: " << endl; v.print(); SmartVector *sPtr = dynamic_cast<SmartVector*>(&v); if(sPtr != nullptr){ cout << "Got a Smart Pointer with length " << sPtr->length() << endl; } } int main() { SimpleVector u(1,2); SimpleVector v(3,4); cout << "u = " ; u.print(); cout << "v = " ; v.print(); SmartVector s(1,5); cout << "s = " ; s.print(); cout << endl; printVector(u); printVector(v); printVector(s); }
SimpleVector.cpp
#include <iostream> #include "SimpleVector.h" using namespace std; SimpleVector::SimpleVector(int _x, int _y) : x(_x),y(_y) { cout << "Simple Vector generated" << endl; } SimpleVector::~SimpleVector() { cout << "Simple Vector deleted" << endl; } void SimpleVector::print() { cout << "(" << x << "/" << y << ")" << endl; }
SimpleVector.h
#ifndef SIMPLEVEC_HPP #define SIMPLEVEC_HPP class SimpleVector{ public: SimpleVector(int _x, int _y); ~SimpleVector(); // mit virtual wird die überladene Funktion aus der Abgeleiteten // Klasse benutzt, wenn das eigentliche Basisklassen Objekt zuvor // aus einer Abgeleiteten Klasse in die Basisklasse gecastet wurde // (z.B. durch einen Funktionsaufruf) virtual void print(); protected: int x,y; }; #endif
SmartVector.cpp
#include <iostream> #include <cmath> #include "SmartVector.h" using namespace std; double SmartVector::length() { return sqrt(x*x+y*y); } void SmartVector::print() { SimpleVector::print(); cout << "Length = " << length() << endl; }
SmartVector.h
#ifndef SMARTVEC_HPP #define SMARTVEC_HPP #include "SimpleVector.h" class SmartVector : public SimpleVector { public: //Hiermit werden alle Konstruktoren aus der Basisklasse kopiert using SimpleVector::SimpleVector; double length(); void print(); }; #endif
Standard-Container und Templates
main.cpp
#include <iostream> #include <vector> #include <array> #include <map> #include <algorithm> using namespace std; class Point{ public: int x,y; friend ostream& operator<<(ostream& os, const Point& point); }; //Überladen des operator<< um die Klasse direkt an cout zu übergeben ostream& operator<<(ostream& os, const Point & point) { os<< point.x << "/" << point.y; return os; } template <typename Container> void printContainer(const Container & container) { for(const auto & element : container){ cout << element << "/"; } cout << " <---" << endl; } int main() { array<int,5> arr1 {1,2,3,4,5}; array<float,5> arr2 {1.,2.,3.,4.,5.}; vector<int> vec1; vector<int> vec2(5); vector<int> vec3(10,1); for(int i=0; i<100; i++){ vec1.push_back(i*i+5); } vector<vector<int>> vecvec {{1,2,3},{4,5,6,5,4},{3,2}}; vector<Point> ptVec; for(int i=0; i<20; i++){ ptVec.push_back({i,i*i+20}); } printContainer<array<int,5>>(arr1); printContainer<array<float,5>>(arr2); printContainer<vector<int>>(vec1); printContainer<vector<int>>(vec2); printContainer<vector<int>>(vec3); printContainer<vector<Point>>(ptVec); cout << "Begin+2 = " << *(arr1.begin()+2) << endl; cout << "Begin+2 = " << arr1.begin()[2] << endl; cout << "End-1 = " << arr1.end()[-1] << endl; //Range based loop for(auto & e : arr1){ e += 10; cout << e << "/"; } cout << endl; printContainer<array<int,5>>(arr1); cout << "Sortierte Vectoren" << endl; for(auto & v : vecvec){ sort(v.begin(),v.end()); printContainer<vector<int>>(v); } // dies geht mit dem überladenen Operator<< cout << ptVec[0] << endl; return 0; }
klasse.cpp
#include <iostream> using namespace std; class MyVector { public: MyVector(); MyVector(float x_, float y_); ~MyVector(); void print(); float getX(){return x;}; void setX(float x_){ x = x_;}; private: float x,y; }; MyVector::~MyVector() { } MyVector::MyVector() { x = 0.5; y = 0.9; } MyVector::MyVector(float x_, float y_) : x(x_),y(y_) { } void MyVector::print() { cout << "x(" << x << ") "; cout << "y(" << y << ") " << endl; } int main() { MyVector v1; v1.print(); MyVector v2(1.6,5.5); v2.print(); return 0; }