Wozu immer Zeiger?



  • Noobfire schrieb:

    Ich frage mich nur, was denn der genaue Vorteil von Zeigern ist..
    Klar, man kann so in einer Funktion eine überlieferte Variable sozusagen extern verändern..

    Mit Zeigern kann man Objekte, Variablen, etc.,verändern ohne erst davon eine Kopie erstellen zu müssen. Das spart Speicherplatz und ist schneller.

    Wenn einer Funktion z.B. ein Objekt (z.B. bei einer Datenbank ein Datensatz mit zig Eigenschaften) als Wert übergeben werden soll, müßte im Prinzip das ganze Objekt in den Speicher der Funktion kopiert werden.

    Falls diese Funktion dann sogar noch andere Funktionen aufruft, müßte das Objekt womöglich nochmal kopiert werden.



  • Zusammengefasst:
    Zeiger braucht man für:
    Bäume
    verkettete Listen
    Effizienz
    Proxies
    dynamische Allokation
    Objekte auf dem Heap mit nicht-lokaler Lebenszeit
    Zeiger oder Referenzen braucht man für:
    Effizienz
    Polymorphie
    Referenzen braucht man für:
    Syntaxzucker/Nachbildung eingebauter Typen

    Es gibt bestimmt noch mehr Dinge, aber das waren jetzt mal einige.



  • @wxSkip
    Naja, brauchen tut man Zeiger eigentlich gar nicht 🙂
    Für die von dir erwähnten Dinge sind sie aber praktisch.



  • hustbaer schrieb:

    @wxSkip
    Naja, brauchen tut man Zeiger eigentlich gar nicht 🙂
    Für die von dir erwähnten Dinge sind sie aber praktisch.

    Sagen wir so, wahrscheinlich kann man viele Programme auch ohne Bäume, verkettete Listen etc. schreiben, aber das wird dann Laufzeitkritisch. Für dynamische Speicheranforderungen brauchst du Zeiger, auch wenn sie manchmal durch RAII-Objekte oder wie in funktionalen Sprachen ganz hinter der Implementierung versteckt werden.

    Also kann man sagen, dass man Zeiger schon braucht. Sie müsssen aber nicht im Code auftauchen (z.B. auch Stack-Pointer o.ä. 😉 ).


  • Mod

    Du könntest alles in großen globalen Arrays machen und Indizes statt Zeiger benutzen. Da kannst du auch wunderbare Bäume mit pflanzen 🙂



  • SeppJ schrieb:

    Du könntest alles in großen globalen Arrays machen und Indizes statt Zeiger benutzen. Da kannst du auch wunderbare Bäume mit pflanzen 🙂

    Super :p . Dann benutzt du halt ints als Zeiger. Und bei der Indizierung werden im Endeffekt doch wieder Zeiger addiert.


  • Mod

    Argh. Verdammter Arrayzugriff 😡 . Ja, da ist ein Zeiger in der Implementierung versteckt. Irgendwie bekommt man den bestimmt auch noch weg :p .



  • SeppJ schrieb:

    Argh. Verdammter Arrayzugriff 😡 . Ja, da ist ein Zeiger in der Implementierung versteckt. Irgendwie bekommt man den bestimmt auch noch weg :p .

    Und dann ist da immer noch der Stack-Pointer, damit du auf deine ints auch zugreifen kannst. :p
    Damit du keine Zeiger brauchst, müsste jedes Programm mit den Registern auskommen. Und das wage ich zu bezweifeln.


  • Mod

    wxSkip schrieb:

    Und dann ist da immer noch der Stack-Pointer, damit du auf deine ints auch zugreifen kannst. :p

    Ach, ich arbeite auf irgendeiner exotischen Maschine ohne Stack 😋 . Das ist vom Standard erlaubt. 🕶

    Aber den Arrayzugriff ohne Pointer zu machen ist tatsächlich ganz schon tricky. Da fällt mir so spontan nichts als Ersatz ein.



  • SeppJ schrieb:

    wxSkip schrieb:

    Und dann ist da immer noch der Stack-Pointer, damit du auf deine ints auch zugreifen kannst. :p

    Ach, ich arbeite auf irgendeiner exotischen Maschine ohne Stack 😋 . Das ist vom Standard erlaubt. 🕶

    Aber den Arrayzugriff ohne Pointer zu machen ist tatsächlich ganz schon tricky. Da fällt mir so spontan nichts als Ersatz ein.

    So exotisch ist doch eine Turingmaschine gar nicht 😕


  • Mod

    wxSkip schrieb:

    So exotisch ist doch eine Turingmaschine gar nicht 😕

    Auf dem Papier und im Simulator nicht. In der Praxis schon irgendwie. Es gibt da die LEGO Mindstorms Version die man bei Youtube finden kann und ein paar weniger coole Hobby-Projekte. Ob die wohl einen C++-Compiler haben?



  • Ich bin sehr gespannt, was das für eine Turingmaschine ohne Befehlszeiger sein soll. Das funktioniert ja nicht mal auf dem Papier?



  • cooky451 schrieb:

    Ich bin sehr gespannt, was das für eine Turingmaschine ohne Befehlszeiger sein soll. Das funktioniert ja nicht mal auf dem Papier?

    Befehlszeiger? Man muss halt den (mechanischen) Schreib-/Lesekopf inkrementell bewegen.



  • wxSkip schrieb:

    Befehlszeiger? Man muss halt den (mechanischen) Schreib-/Lesekopf inkrementell bewegen.

    Das ist für mich trotzdem ein Zeiger, ändert ja nichts an dem Konzept..



  • cooky451 schrieb:

    wxSkip schrieb:

    Befehlszeiger? Man muss halt den (mechanischen) Schreib-/Lesekopf inkrementell bewegen.

    Das ist für mich trotzdem ein Zeiger, ändert ja nichts an dem Konzept..

    Dann sind aber auch die ints von SeppJ für den Arrayzugriff Zeiger.



  • wxSkip schrieb:

    Dann sind aber auch die ints von SeppJ für den Arrayzugriff Zeiger.

    Ja, klar.

    SeppJ schrieb:

    Argh. Verdammter Arrayzugriff 😡 . Ja, da ist ein Zeiger in der Implementierung versteckt.



  • Nein, ich meinte, schon die ints selber werden relativ zum Arrayanfang als Zeiger (miss/ge)braucht (genau wie der Schreib-/Lesekopf bei meinem Beispiel). Danach ist sowieso Zeigerarithmetik involviert.


  • Administrator

    SeppJ schrieb:

    2. Dafür würden sie komische Probleme bringen: Was soll zum Beispiel der Typ eines solchen Arrays sein und wann steht er fest? Auf diese Frage gibt es keine befriedigende Antwort und das in einer Sprache in der Typen dermaßen wichtig sind!

    Frage am Rande: Wie wurde dies eigentlich in C99 gelöst?

    Grüssli


  • Mod

    Dravere schrieb:

    Frage am Rande: Wie wurde dies eigentlich in C99 gelöst?

    Die genauen Details müsste ich selber nachschlagen. Aber die C99 Umsetzung ist berühmt berüchtigt. Die Grundidee ist, dass die Arrays tatsächlich den Typ VLA haben. Solche Typen haben starke Einschränkungen, können unter anderem nicht in structs oder unions auftauchen und auch nicht extern sein (das gilt auch für Pointer auf diese Typen). sizeof funktioniert jedoch wie erwartet und wird zur Laufzeit ausgewertet. Auch typedefs sind möglich, diese werden dann auch zur Laufzeit ausgewertet, wenn der Programmfluss an dem typedef vorbei kommt.

    Insgesamt recht kompliziert. Gefühlt jeder zweite Absatz im C99-Standard hat eine Sonderklausel für VLAs.



  • Am Anfang kam dieses eine Code-Beispiel. Hier mal eine andere Variante.

    void verdoppeln(int &var)
    {
     var *= 2;
    }
    
    //[...]
    int test = 2;
    verdoppeln(test);
    // test = 4
    //[...]
    

    Kann man da sagen, welche besser oder zu bevorzugen ist? Und wenn ja, warum?


Anmelden zum Antworten