Problem mit einfach-verketteter Liste
-
prolahmierer schrieb:
Also ich steh da irgendwie auf dem Schlauch! Genau da liegt mein Problem. hd ist doch schon ein Zeiger. Ich dachte wenn man Zeiger nimmt bezieht man sich auf die Adresse. Wieso muss denn da jetzt noch ein Stern davor? Dann ist es ja ein Zeiger auf einen Zeiger
Okay... Back to the roots...
Du hast einen Zeiger auf Liste ne Liste. ( slptr hd = 0; )
Wenn du an diesen Zeiger jetzt an deine Funktion übergeben willst, dann hast du das hier gemacht. ( void append(slptr hd, char data[MAXLEN]) )Was geschieht hier... Der Variable wird kopiert, d.h. byValue.
=> hd = 0; (am Start deiner Funktion innerhalb und außerhalb der Funktion / d.h. momentan eine exakte Kopie von einander.Jetzt kommen wir an die Stelle if(!hd) .
Genau dieser Fall tritt ja bei einer leeren Liste auf:
Jetzt kommt der Fehler:
hd = neu;Weil hd in der Funktion und hd außerhalb der Funktion nur KOPIEN von einander sind hat hd in der funktion den Wert von neu und hd außerhalb der Funktion immer noch den wert 0.
Du willst hier aber eine Adresse beeinflussen, also brauchst du die Adresse der Adresse (den berühmten Zeiger-Zeiger) um das Problem zu lösen, denn dann schreibst du das genau dahin wo du es hinschreiben willst, nämlich in hd.
Also merke:
Wenn eine Funktion einen Wert eines Parameters verändern soll, musst du in C++ ihn per Referenz oder in C seine Adresse (dann natürlich byValue) übergeben...Verstanden?
-
Ah ich glaub jetzt hab ichs, vielen Dank
Diese Zeiger können einen echt wahnsinnig machen
-
Ich liebe Zeiger... Sie können einen wahnsinnig machen, aber damit weiß der Programmierer immer genau was Sache ist...
Gern geschehen
-
BikingGlobetrotter schrieb:
Unter C++ kannst du einfach das folgende machen (also einfach das & dahin)
void append(slptr & hd, char data[MAXLEN])
Unter C musst du folgendes nehmen, aber damit wird alles zu Adressen, die du erst wieder dereferenzieren musst.
void append(slptr* hd, char data[MAXLEN])
also, ich halte die C-version für besser. da sieht man wenigstens, was passiert.
-
fricky schrieb:
also, ich halte die C-version für besser. da sieht man wenigstens, was passiert.
Jedem das seine. Ich finde C++ schöner, vor allem weil es halt schön objektorientiert ist...
und an Referenzen gewöhnt man sich schnell. Vor allem, wenn man mit Java programieren gelernt hat...
-
BikingGlobetrotter schrieb:
Ich finde C++ schöner, vor allem weil es halt schön objektorientiert ist...
'schön' objektorientiert ist was anderes.
BikingGlobetrotter schrieb:
...und an Referenzen gewöhnt man sich schnell. Vor allem, wenn man mit Java programieren gelernt hat...
naja, aber in java funktionieren referenzen eher so, wie in C die pointer.
-
fricky schrieb:
BikingGlobetrotter schrieb:
Unter C++ kannst du einfach das folgende machen (also einfach das & dahin)
void append(slptr & hd, char data[MAXLEN])
Unter C musst du folgendes nehmen, aber damit wird alles zu Adressen, die du erst wieder dereferenzieren musst.
void append(slptr* hd, char data[MAXLEN])
also, ich halte die C-version für besser. da sieht man wenigstens, was passiert.
Klar, das & verschleiert diese Tatsache auch völlig
Eine Sprache kann natürlich nur von dem verstanden werden die sie kann
Dass die C++-Variante gravierende Vorteile hat lass ich jetzt sogar einmal außen vor.
-
Rubbel die Katz schrieb:
Dass die C++-Variante gravierende Vorteile hat lass ich jetzt sogar einmal außen vor.
Erzaehl man, welchen Vorteil hat die C++ Variante?
-
Rubbel die Katz schrieb:
Dass die C++-Variante gravierende Vorteile hat lass ich jetzt sogar einmal außen vor.
das sagst du doch nur, weil dir keine einfallen.
-
supertux schrieb:
Rubbel die Katz schrieb:
Dass die C++-Variante gravierende Vorteile hat lass ich jetzt sogar einmal außen vor.
Erzaehl man, welchen Vorteil hat die C++ Variante?
Keine... ist genau das selbe... Ausser das du beim Funktionsaufruf nicht "&variable" schreiben musst (falls es noch kein pointer ist) sondern direkt schreibst "variable"...
Sehe ich übrigens nicht soooo positiv, da du nicht weißt was genau die funktion erwartet und ob sie deine Variable verändert...
~(alle angaben ohne gewähr: vllt waren die paar c++ wochen von mir auch zu wenig und ich habe alles verraft und der post ist falschm, dann ignoriert ihn einfach xD)~
-
lippoliv schrieb:
Sehe ich übrigens nicht soooo positiv, da du nicht weißt was genau die funktion erwartet und ob sie deine Variable verändert...
das sach ich ja auch immer. bei c++ muss man immer höllisch aufpassen, was man tut. C ist da weitaus geradliniger und birgt weniger fallen für den benutzer.
-
Es reduziert die Komplexität um eine Größenordnung, das ist ein entscheidender Vorteil.
Dass ihr C-Hacker eure ganzen kryptischen & und * vor dem Variablen braucht um euch wohl zu fühlen sehe ich auch nach und belasse es dabei.
-
L0L ficky schrieb:
Es reduziert die Komplexität um eine Größenordnung, das ist ein entscheidender Vorteil.
wenn, dann verbirgt es komplexität. und das muss nicht immer ein vorteil sein, vor allem dann nicht, wenn die lesbarkeit des codes darunter leidet.
btw, http://yosefk.com/c++fqa/ref.html
--> vor allem punkt 8.6
-
lippoliv schrieb:
Keine... ist genau das selbe... Ausser das du beim Funktionsaufruf nicht "&variable" schreiben musst (falls es noch kein pointer ist) sondern direkt schreibst "variable"...
stimmt, dass du bei einer Referenz wuerde man den Variablennamen ohne & schreibst. Und wo liegt darin der Vorteil? Ich sehe darin eher einen Nachteil (siehe unten)
L0L ficky schrieb:
Es reduziert die Komplexität um eine Größenordnung, das ist ein entscheidender Vorteil.
Inwiefern reduziert das die Komplexitate? Welche Komplezitat? In C weiß ich wenigstens auf einen Blick, dass meine Variable sich veraendern kann:
slptr hd; hd.waswasich = setzen; ... append(&hd, "der C Fall");
da sehe ich sofort, dass append meine Variable hd veraendern kann. Wenn ich das nicht will, dann kann ich eine Kopie von hd machen und diese Uebergeben.
slptr hd; hd.waswasich = setzen; ... append(hd, "der C++ Fall");
Wenn nach langer Zeit ich den C++ Prototyp von append nicht mehr kenne, erkenne ich nicht daran, ob hd sich aendert oder nicht. Ich weiß es nicht. Das koennte wichtig sein.
Aber unabhaengig davon, ob man auf den ersten Blick eine Variablenaenderung sieht oder nicht: Wo bitte ist im C++ Fall eine Reduktion der Komplexitaet bzw. wo ist in C komplexer?
-
@supertux
in c++ kann man 'const' benutzen, um seine variablen vor manipulation durch referenzen zu schützen. das ist natürlich nur, ääääh, sagen wir mal sowas wie ein workaround. was aber nicht sonderlich auffällt, denn c++ coder sind per se vertraut mit vielen workarounds und hacks.
-
supertux schrieb:
Inwiefern reduziert das die Komplexitate? Welche Komplezitat?
Die Sichtbare. Genauso wenig wie es sinnvoll ist, diese stets zu verstecken, ist es praktisch, wenn die Sprache kein Mittel bereitstellt, sie an sinnvollen Stellen zu verdecken. C++ ermöglicht die Wahl (man kann ja immer noch per Zeiger übergeben und ich bin nicht der Ansicht, dass eine Variante der anderen gegenüber generell überlegen ist) C tut das nicht.
Zunächst einmal ist die Frage, ob ein Parameter verändert wird oder nicht, nicht primär eine der Funktionssignatur (die nur Mittel zum Zweck ist), sondern eine der Funktionalität. Selbst wenn dir die konkrete Signatur eine Funktion entfallen ist, wirst du sie kaum aufrufen, ohne zu wissen was tut (wenn das vergessen wurde, hilft dir auch ein Zeigerargument nicht). Ist eine Funktion sinnvoll definiert worden, ist ein veränderliches Argument aber stets eine notwendige Folge (oder nicht), es wird also durch die Funktionalität in aller Regel impliziert (natürlich gibt es für alles und jedes Ausnahmen, wenn man darauf hinweisen muss, kann man ja z.B. Zeiger verwenden...).
Andererseits ist es in den Fällen, in denen diese Frage absolut offensichtlich ist, oft schlicht überflüssig (und in Hinblick auf den aufrufenden Code oft auch schlich wenig relevant), noch einmal beim Funktionsaufruf mit & darauf hinzuweisen lenkt dann also vom Wesentlichen ab. Zudem leiden C und C++ bereits unter einer Syntax mit viel zu vielen Sonderzeichen.
Um es kurz zu fassen, Referenzargumente sind natürlich kein Allheilmittel, aber sie können nützlich sein und C++ lässt einem die Wahl, ob man sie verwenden will, und das ist eine gute Sache. Schließlich ging man beim Design beider Sprachen von umsichtigen Programmierern aus, denen man solche Entscheidungen überlassen kann.Edit: ups, jetzt hab ich doch im falschen Forum geantwortet... also einfach ignorieren, wenn kein Interesse besteht,
-
camper schrieb:
supertux schrieb:
Inwiefern reduziert das die Komplexitate? Welche Komplezitat?
Die Sichtbare. Genauso wenig wie es sinnvoll ist, diese stets zu verstecken, ist es praktisch, wenn die Sprache kein Mittel bereitstellt, sie an sinnvollen Stellen zu verdecken. C++ ermöglicht die Wahl (man kann ja immer noch per Zeiger übergeben und ich bin nicht der Ansicht, dass eine Variante der anderen gegenüber generell überlegen ist) C tut das nicht.
zugegeben habe ich ein Problem damit, die (von dir genannte) sichtbare Komplexitaet ueberhaupt zu erkennen. Ich bin kein C++ Guru, deswegen kann es sein, dass mir die Erfahrung von Referenzen vs. Zeiger fehlt. Gerade am
apppend
Beispiel sehe ich keine "sichtbare" Komplexitaet seitens C. Du schreibst auch "noch einmal beim Funktionsaufruf mit & darauf hinzuweisen lenkt dann also vom Wesentlichen ab", wie ist das zu verstehen? Ablenken, vowor? Irgendwie kann ich da die Argumentation nicht verstehen.
-
supertux schrieb:
lippoliv schrieb:
Keine... ist genau das selbe... Ausser das du beim Funktionsaufruf nicht "&variable" schreiben musst (falls es noch kein pointer ist) sondern direkt schreibst "variable"...
stimmt, dass du bei einer Referenz wuerde man den Variablennamen ohne & schreibst. Und wo liegt darin der Vorteil? Ich sehe darin eher einen Nachteil (siehe unten)
Nein ich bin C-ler... ich schreibe das und.
Ich stimme dir zu, ich kennzeichne lieber nochmal die Variable so, das ich beim Funktionsaufruf sehe, welche verändert wird, anstatt einfach blind die Variablen in die Funktionen zu schmeißen und zu schauen was bei rauskommt...