switch language to english

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


Hier 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;
  }



zum Seitenanfang