Konsolenbefehl mit Argumenten

Werden in der Konsole Argumente mitgegeben

./video 50070 -1                    // [port] [dumped]

so müssen diese im Executable verarbeitet werden.

int main(int argc, char *argv[]) {

   // set configruations

    if (argc > 1) {
        Port = atoi(argv[1]);
        ....
    }

    if(argc > 2) {
       if (atoi(argv[2]) == -1) {
          ..  // open dumped-file
        }
       else if (atoi(argv[2]) == 1) {
          ..  // open ...
        }
    }

 

 

 

 

 

 

Klasse Definition

class Token_stream {
    public:
        void set(string line);
        Token get();
        void put_back(Token t);
    private:
        istringstream calculation;
        bool full = false;
        Token buffer;
};

Eine Klasse beinhaltet Klassenvariablen und Klassen-Funktionen.

Instanzierung

Token_stream current_token_stream;

current_token_stream ist eine Instanz dieser Klasse. Alle Funktionen (die gebraucht werden um die Instanz zu verarbeiten) brauchen zuerst den Instanznamen.

current_token_stream.set(calculation_line);

 

Klassen-Funktionen
Jede Funktion einer Klasse muss nach der Klassendefinition definiert werden. Die Funktion braucht vor ihrem Namen die Klasse, zu der sie gehört.

void Token_stream::put_back(Token t) {
    
    // check if token is already in buffer
    if (token_buffer_full) {
        throw std::overflow_error("buffer contains already a Token");
    }
    
    // set token in buffer
    token_buffer = t;

    token_buffer_full = true;
}

Funktionen einer Klasse, müssen nicht forward deklariert werden. Sie sind durch die Definition der Klasse bereits bekannt.

Klassen-Variablen
Es gibt meist wenige Klassenvariblen. Denn diese sind „global“ innerhalb der Klasse. Alle Funktionen können auf diese Zugreifen.

class Token_stream {
    ...
    private:
        istringstream calculation;
        bool full = false;
        Token token_buffer;
};

Typisch ist, dass sie im private-Teil der Klasse stehen.

Lokale Variablen
In jeder Klassen-Funktion werden zur Verarbeitung auch lokale Variablen gebraucht.

Token Token_stream::get() {

    char c;
    Token t;

    calculation >> c;

    if (isdigit(c)) {
        t.kind = 'n';
        t.value = c;
    } else if (c == '\0') {
        t.kind = 'q';
    } 

    return t;
}

 

self in Klassen [aus: swift]

Die Variable self wird nur gebraucht, wenn das Argument einer Funktion denselben Namen hat wie eine Klassenvariable.

Mit self.variable wird die Klassenvariable bezeichnet bzw. unterschieden von dem Argument.

class TipCalculator {
   let total: Double
   let taxPct: Double
   let subtotal: Double

   init(total: Double; taxPct: Double) {
       self.total = total      // Argumente erhalten
       self.taxPct = taxPct
       subtotal = total /(taxPct+1)   // keine Argumente
                                 // nur Klassenvariable
   }


}

aus: Swift 2 Tutorial

DebugNavitator XCode

Fensterübersicht
Das fünfte Fenster im Navigator dient dem Debuggen.
Das Fenster links (1) heisst Stack View. Es zeigt alle Aufrufe (Ablagen auf dem Stack) bis zum aktuellen Programmpunkt. Zu unterst im Stack ist das main(), dann folgen alle aufrufe. Theoretisch kann man die Grösse der Stack-Details durch die Bedienung zu unterst am Fenster einstellen (nur Aufrufe, auch Variablen, …). Bei der hier abgebildeten Funktion war dies nicht möglich.
Das Fenster unten links (2) nennt sich Variable View. Durch Klicken auf das Dreieck vor der Variable, erhält man mehr Details. Man kann über das Menü ganz unten festlegen, ob man nur die lokalen Variabeln (aktuelle Einstellung) oder alle oder AUTO sehen will.
Das Fenster (3) ist die Konsole.

Fenster_DebuggNavigator

Debugg-KnöpfeDebuggKnoepfe_DebuggNavigator

  • CONTINUE: Verlässt die aktuelle Debugging-Stelle. Das Programm läuft weiter bis zum nächsten Breakpoint.
  • STEP OVER: Aktuelle Zeile wird ausgeführt. Cursor geht zur nächsten Zeile.
  • STEP INTO: Sprung von der aktuellen Stelle in die Funktion. Man sieht wohin das Programm geht und wie die Variablen gesetzt werden
  • STEP OUT: Verlassen der aufgerufenen Funktion. Man kehrt an die Debugging-Stelle zurück.

Variablen währende dem Debuggen temporär setzen
Im zweiten Fenster (Variable View) können während dem das Debuggen läuft, also der Code ausgeführt wird, Variablen-Werte manuell gesetzt werden. Man sieht dann, wie sich das auf den Code auswirkt.

 

 

 

 

 

Debuggen mit Breakpoints

Grundsätzlich

  • Breakpoints werden bei Anweisungen gesetzt
  • Bei Deklarationen und Definitionen werden sie nicht gesetzt

Steuerung des Ablaufs

  • Stoppt das Programm bei einem BREAKPOINT, so ist diese Anweisung nocht nicht ausgeführt. Man sieht den Zustand VOR der Anweisung.
  • STEP OVER: Die aktuelle Zeile wird ausgeführt. Der Cursor springt zur nächsten Zeile.
  • STEP INTO: Das Programm geht IN die Anweisung. Man sieht den Funktionsauftruf , alle Variablen der Funktion und den Ablauf
  • STEP OUT: Der Aufruf wird verlassen und man kehrt zum Ort zurück, an dem der Aufruf stand.
    (Verlassen des Aufrufes kann sehr hilfreich sein, wenn die Funktion sehr lang ist oder ein for-loop auf 20 zählt und man nicht jede Anweisung durchklicken will.)
  • CONTINUE: Man verlasst die aktuelle Codestelle und springt bis zum nächsten Breakpoint.
    Die aktuelle Debugstelle wird verlassen.

keyword protected

public:
Überall kann auf die Variable zugegriffen werden. In anderen Files, in anderen Funktionen, …

private:
Nur in der Klasse selbst kann auf die Variable zugegriffen werden. Innerhalb der Klassenfunktionen oder beim Instanzieren.

protected:
Von aussen kann auf diese Variable nicht zugegriffen werden. Jedoch alle abgeleiteten Objekte, können auch darauf zugreifen. Die Variable gilt nicht nur in 1 Klasse, sondern in allen abgeleiteten Klassen ebenfalls.

Klasse aufbauen

Die Klasse dient zum spezifischen Verarbeiten eines Objektes.

Das Objekt wird mit em Konstruktor gebildet Klasse::Klasse()

klasse

Um auf das Objekt zuzugreifen, es zu verändern oder den Zustand seiner Variablen zu kennen braucht man Klassen-Funktionen Klasse::funktion() .

Auf alle Klassenvariablen kann man nur über das Objekt zugreifen objekt.variable .

Bsp Huffman Map
– Konstruktor bildet die Map- hm.readToken(„stream.txt“)  Daten werden von aussen eingegeben und lokal im Objekt gespeichert
– hm.getBitValue()    Lokale Varibale wird verarbeitet und ausgegeben
– hm.getZeros()         Andere Variable wird verabeitet und ausgegeben

 

per Reference C++, per Pointer C, C++

Grund
Will man mehrere externe Variable in einer Funktion bearbeiten, hat aber nur einen return Wert, so gibt man die Adressen dieser Variablen als Paramter mit. Dadurch wird die Variable direkt durch die Funktion bearbeitet. (Die Alternative wäre, globale Variablen zu definieren und diese zu übergeben. Da globale Varibalen vermieden werden sollen, entfällt diese Alternative.)

Pointer übergeben (C und C++)

function(int *x){do someting}    // Deklaration: Parameter ist ein Pointer

int a ;
function(&a);                    // Argument: Adresse der Variable

Bei der Übergabe per Pointer, wird keine lokale Kopie des Arguments erstellt, sondern die Änderungen werden direkt in den Speicher geschrieben.

Per Reference übergeben (C++)

function(int &x);           // Deklaration: Parameter einer Variable per Ref.
int a;
function(a);                // Die Adresse des Arguments wird genommen

Bei per Reference geschieht das selbe wie beim Pointer. Nur sieht man es beim Argument nicht direkt. Die Variable wird „normal“ übergeben.
Trotzdem ist die Wirkung die selbe wie bei der Pointerübergabe: Wie bei einer gobalen Varibale wird durch die Funktion die externe Variable verändert (LINK)

c++ Operator overloding

Kapitel 9: Operatoren nicht nur für Integers
(Übung Buchhandlung mit Christian: == für den Vergleich der Klasse Buch)

class Book {
private:
    string ISBN;
    string title;
    string author;
public: 
    Book(string isbn, string t, string a){ 
        ISBN = isbn; 
        title = t; 
        author = a; 
}

// buch1 == buch2

bool operator==(const Book& b2)       // new Datatyp is Book
  {
    if(ISBN == b2.ISBN)               // this new Typ is addresd by b2
      return true;
    else
      return false;
  }
Book buch1 = Book{978-8-123-12345-6, "Andorra", "Frisch"};
Book buch3 = Book{978-8-123-12345-6, "Mein Name ist Gantenbein", "Frisch"};
if (buch1 == buch3)
    cout << "Die Bücher sind gleich." << endl;
  else
    cout << "Die Bücher sind nicht gleich." << endl;

Hier sind buch1 und buch3 gleich, weil sie die gleichen ISBN haben.

 

Kapitel 10: IO
Der Operator << ist ursprünglich nur für String.
Sollen bei << auch andere Datentypen übergeben werden können, braucht es ein Overloading.

ostream& operator <<(ostream& os, const Date& d)

Ab sofort kann auch die Klasse Date dem stream übergeben werden.

 

 

 

 

..