Informatik W11
Levin Ceglie
Outine
- Quiz
- Pointers
- Datenstrukturen und Iteratoren
Pointers
Ein Pointer oder auch Zeiger ist ein C++ Objekt, das auf eine Speicheradresse zeigt. Die Adresse eines Objekts a können wir immer mit &a ausgeben (nicht verwechseln mit Referenz).
Initialisierung
Ein Pointer wird im Allgemeinen mit
Typ* name;initialisiert, wobei der Typ dem Typen der Adresse entsprechen muss.
Dereferenzierung
Um das tatsächliche Objekt zu erhalten, auf welches ein Pointer zeigt, dereferenziert man den Pointer. Dies geschieht mitters dem * Operator. Zum Beispiel wie folgt falls p ein Pointer auf ein Objekt ist, für welches die Ausgabe mittels << definiert ist:
std::cout << *p;Nullpointer
Mit Typ* p = nullptr lässt sich ein Pointer erstellen, der “ins Nichts” zeigt, das heisst er zeigt auf keine Speicheradresse.
Achtung: Das dereferenzieren eines nullptr führt zu einem Error.
Die Symbole & und * in C++
In C++ hat das Symbol & drei verschiedene Bedeutungen, abhängig davon, wo es steht:
- Der logische UND-Operator.
Beispiel:bool valid = a && b; - Deklaration einer Variable als Referenz.
Beispiel:int& x = a; - Zugriff auf Adresse einer Variablen.
Beispiel:int* p = &a;
Das Symbol * hat ebenso drei verschiedene Bedeutungen, abhängig davon, wo es steht:
- Arithmetischer Multiplikationsoperator.
Beispiel:int x = 3 * a; - Deklaration einer Pointer Variable.
Beispiel:int* p = &a; - Dereferenzierungsoperator eines Pointers, um auf die Speicherstelle zuzugreifen.
Beispiel:int a = *p;
Constness
Wie bei den üblichen Datentypen, gibt es auch die Möglichkeit konstante Pointer zu definieren. Dies geschieht mit Typ* const p;. Als Faustregel, kann man den Datentyp von rechts nach links lesen, so würde man int* const p; lesen als “konstanter (const) pointer (*) auf einen Integer (int). Weitere Beispiele:
int* p; // => dynamischer Pointer auf dynamischen Wert
const int* p; // => dynamischer Pointer auf konstanten Wert
int const* p; // => dynamischer Pointer auf konstanten Wert
int* const p; // => konstanter Pointer auf dynamischen Wert
const int* const p; // => konstanter Pointer auf konstanten WertDatenstrukturen und Iteratoren
Aufgabe (our_list::init)
Zusammen our_list.h durchgehenund Fragen klären. Danach individuel Aufgabe lösen.
Lösung:
our_list::our_list(our_list::const_iterator begin, our_list::const_iterator end) {
this->head = nullptr;
if (begin == end) {
return;
}
// Let's add the first element from the iterator.
our_list::const_iterator it = begin;
this->head = new lnode { *it, nullptr };
++it;
lnode *node = this->head;
// Let's add all the remaining elements.
for (; it != end; ++it) {
node->next = new lnode { *it, nullptr };
node = node->next;
}
}Aufgabe (our_list::swap)
Lösung:
void our_list::swap(unsigned int index) {
lnode* prev = nullptr;
lnode* curr = this->head;
bool swap_head = index==0;
// Find the element.
while (index > 0) {
prev = curr;
curr = curr->next;
--index;
}
assert(curr != nullptr);
assert(curr->next != nullptr);
// Swap with the next one.
lnode* tmp = curr->next;
curr->next = curr->next->next;
tmp->next = curr;
if(swap_head){
this->head = tmp;
}
else{
prev->next = tmp;
}
}Aufgabe (our_list::extend)
Lösung:
void our_list::extend(our_list::const_iterator begin, our_list::const_iterator end) {
if (begin == end) {
return;
}
our_list::const_iterator it = begin;
if (this->head == nullptr) {
this->head = new lnode { *it, nullptr };
++it;
}
lnode *n = this->head;
while (n->next != nullptr) {
n = n->next;
}
for (; it != end; ++it) {
n->next = new lnode { *it, nullptr };
n = n->next;
}
}