Krautkanal.com

Veröffentlicht am 2015-01-26 19:08:3 in /prog/

/prog/ 6473: C(lassic)

jjshaw14 Avatar
jjshaw14:#6473

Lieber Bernd,

Bernd wiederholt gerade sein C. Er fand heute zufällig irgendwelche Schmierereien aus alten Tagen zu Pointern und versucht nun die Syntax zu entschlüsseln.
Es ging höchtstwahrscheinlich um eine ringverkettete Liste und die Löschung einzelner Knoten aus dieser.

Angenommen, Knoten:

typedef struct knoten{
int daten;
knoten* next;
knoten* prev;
};


Nun steht auf diesem verfickten Zettel:

tmp->prev->next=tmp->next

Ich würde _sehr gerne_ wissen, ob diese Syntax stimmt, man sie verwendet und was sie bedeutet.

Vermutung:

0. Ich meine, mich zu erinnern, dass tmp, prev, next Zeiger auf Knoten sind ("->" zufolge sein müssen).
Heißt das ganze nun, dass
1. indirekt auf die Komponente "prev" von der Struktur, auf die tmp zeigt, zugegriffen wird
2. Dieser Zeiger dereferenziert und
3. in die Komponente "next" der Struktur, auf die der Zeiger aus 2. zeigt, der Inhalt von "tmp->next" geschrieben wird?


Bei Bedarf suche ich alte Lösung und poste. Bin jedoch nicht sicher, ob ich o. g. Zauber verwendet habe.
Kann mich aber an Segfaults iVm o. g. Pfeylerey erinnern.
Auch: war da nicht etwas mit Auswerung von rechts nach links oder umgekehrt?

Dein Bydlocoder-Bernd.

curiousonaut Avatar
curiousonaut:#6477

Ohne weiteres würde ich raten, dass tmp ein Zeiger auf die Struktur namens Knoten ist und diese beinhaltet dann wiederum Zeiger auf den vorherigen und den nächsten Knoten.
In der Zeile wird dann tmp->prev dereferenziert um tmp->prev->next zu beschreiben. Dabei wird tmp wohl aus der Kette genommen.

Wenn es nicht nur eine Übungsaufgabe ist, solltest du vermutlich noch tmp->next->prev=tmp->prev setzen und tmp gegebenenfalls befreien.

bassamology Avatar
bassamology:#6478

>>6477
Danke für den Überflug. OP hier.

1. Befreien, um prinzipiell Speicher zu befreien? - sind ja nur ein paar Adressen.
2. Wäre folgendes effizienter, ohne "tmp"- Swap (muß hier nur &LiKnoten speichern)?

Knoten rechts soll gelöscht werden:

(*LiKnoten).next=(*(*LiKnoten).next).next // einmal rechts übersprungen
// geht auch "LiKnoten->next=LiKnoten->next->next"?
(*(*LiKnoten).next).prev=&LiKnoten // _neuer_ nächster Knoten bekommt Adresse seines neuen Nachbarn.
// geht auch "LiKnoten->next->prev=&LiKnoten"?


IDF nicht dein Compiler - Bernd, Du bist mehr als das.

robergd Avatar
robergd:#6487

>>6473

Hallo,
Du verwendest deinen typedef falsch, soweit ich weiß (ich programmier hauptsächlich C++, da sind solche Kniffe nicht nötig).

typedef struct {
int daten;
knoten* next;
knoten* prev;
} knoten;

// jetzt kannst du mit:
knoten eins;
knoten zwei;
// neuen Knoten definieren.


http://openbook.rheinwerk-verlag.de/c_von_a_bis_z/015_c_strukturen_011.htm

Zu deiner anderen Frage:
tmp->prev->next = tmp->next;

Es ist eine Zuweisung. Es scheint als hättest du vor, den "tmp"-Knoten zu löschen und weist dem Vorgänger von tmp den Nachfolger von "tmp" zu.
Ich vermute, dass der nächste Schritt "free(tmp)" lautet, oder?

// Merke:
*tmp // ist eine dereferenzierung des Zeigers, du kriegst damit den Wert
tmp // ist die Adresse

// Die beiden unteren Ausdrücke sind gleichbedeutend:
tmp->next;
(*tmp).next;

// -> ist "syntaktischer Zucker"


Ich kann auch "C von A bis Z" empfehlen, gibt es als openbook
http://openbook.rheinwerk-verlag.de/c_von_a_bis_z/index.htm

wtrsld Avatar
wtrsld:#6495

>>6487
>Ich kann auch "C von A bis Z" empfehlen
Nein, einfach nur nein.

pjnes Avatar
pjnes:#6576

>>6495

Anderer Bernd hier. Halt die Fresse.

Mit diesem Buch lernte ich C.

zackeeler Avatar
zackeeler:#6577

>>6478
Weil es sonst niemand beantwortet hat:
>Befreien, um prinzipiell Speicher zu befreien? - sind ja nur ein paar Adressen.
Auf einem 64-Bit-System kann so ein struct bis zu 32 Byte belegen (unter Beachtung der Speicherausrichtung). Erzeuge eine leere Liste. Füge ein Element ein. Lösche es. Wiederhole die letzten beiden Schritte eine Milliarde Iterationen lang. Diese Liste sollte stets sehr wenig Platz einnehmen, aber wenn der Speicher nicht jedes Mal befreit wird, sind es am Ende bis zu 30 GiB.

adewaleolaore Avatar
adewaleolaore:#6588

>>6576
Und in der Schule lernt man Lesen und Schreiben. Das ist echt eine super Sache, da in Deutschland Schulpflicht besteht und somit jeder Schulabsolvent beides gut beherrscht.