Zeiger: Sinn | Unsinn.



  • Vielleicht sollte man bei solchen Diskussionen stets zwischen

    (a) MASCHINENNAHER

    und

    (b) NICHT-MASCHINENNAHER (vielleicht wißt ihr einen bessern Ausdruck)

    Programmierung unterscheiden. Wobei a) jene Programmierung zur Steuerung von Maschinen und Maschinenmanipulierung dient, während b) zur grafischen Anwenungen im Stile von Fenstern, Datenbankanwendungen angewendet wird.

    Hierbei ergeben sich nämlich unterschiedliche Problemstellungen und Wünsche. Nicht? (Ergänzend: Und Kostenfaktoren sowie Kostenpunkte und Budgeteinteilungen.)



  • rafa schrieb:

    Hinweis: Mit Zeiger-Problem meinte ich keineswegs Referenzen u.ä., ohne könnte ich gar nicht auskommen.

    OK, aber dafür braucht man eben das Konstrukt "Zeiger", deshalb sag ich das. Auch weil in solchen Diskussionen immer gerne die unterschiedlichen Auffassungen, was eine Referenz ist, unkritisch durcheinandergeworfen werden, was am Ende nur maximale Verwirrung(TM) hinterläßt.

    Und dabei fragte ich mich warum solche Problemstellungen wo anders 'anders' gelöst werden.

    Die Frage ist IMHO eher, warum es in C++ gerade so gelöst ist -- ältere Sprachen haben interessanterweise keine C-mäßigen Zeiger (Beispiele FORTRAN und LISP). Einer der Väter von C muss es wohl besonders lustig gefunden haben, dass man mit Zeigern so einige verschiedene Konzepte zu einem verallgemeinern kann. Dass das ganze dann in einen Typ mündet, der im Prinzip nicht viel mehr als eine numerische Adresse ist, kam ihnen gerade Recht, denn sie wollten damit ein Betriebssystem schreiben.
    Naja, und C++ hat das eben übernommen.



  • Erstens können Objekte nicht explizit freigegeben werden, wodurch das Objekt, auf das ein Zeiger zeigt nie ungültig werden kann (es gibt keine dangling pointer).

    foo = null???

    Zeiger sind eine Mischung aus zwei Modellen, dem des Moikers und dem des Iterators (auch wenn Iteratoren manchmal auch noch was anders sind).

    Und genau aus dieser Mischung entsteht das Problem, da viele mit dem Verhalten als Iterator nicht klar kommen.



  • Helium schrieb:

    foo = null???

    Das setzt den Zeiger auf Null, aber zerstört nicht notwendigerweise das dahinterliegende Objekt. Das kann ja noch von anderen Zeigern referenziert werden. Wenn du ein Objekt explizit zerstörst, kann es immer noch referenziert werden, denn es können beliebig viele Pointer darauf verweisen.

    [ Das betrifft offensichtlich nur eingebaute Sprachmechanismen, über die unterhalten wir uns hier ja, nicht shared_ptr und ähnliches. ]



  • rafa schrieb:

    Es ist keineswegs so, dass ich Zeiger vermeide, aber ich betrachte sie vielmehr
    als Referenzen, und da ich solcherlei bisher anders gelöst habe (vielleicht
    nicht minder schneller) frage mich sehr wohl wozu ich all die 'Möglichkeiten'
    brauche.

    Wohl die meisten Programmierer werden nicht alle Features einer Sprache
    einsetzen. Deswegen kann man diese Features aber noch lange nicht aus der
    Sprache entfernen, denn diese definieren doch die Sprache.

    rafa schrieb:

    Vielleicht sollte man bei solchen Diskussionen stets zwischen

    (a) MASCHINENNAHER

    und

    (b) NICHT-MASCHINENNAHER (vielleicht wißt ihr einen bessern Ausdruck)

    Programmierung unterscheiden. Wobei a) jene Programmierung zur Steuerung von
    Maschinen und Maschinenmanipulierung dient, während b) zur grafischen Anwenungen
    im Stile von Fenstern, Datenbankanwendungen angewendet wird.

    Hierbei ergeben sich nämlich unterschiedliche Problemstellungen und Wünsche.
    Nicht? (Ergänzend: Und Kostenfaktoren sowie Kostenpunkte und
    Budgeteinteilungen.)

    Das ist voellig korrekt. Aber die Sprache C wurde zur Maschinennahen
    Programmierung entwickelt. Das die Sprache auch fuer normale Softwareentwicklung
    eingesetzt wird, daran dachte damals niemand. Da sich C++ an C orientiert
    (oder darauf aufbaut - wie auch immer), ist es nur selbstverstaendlich, dass
    Zeiger weiterhin Bestandteil dieser Sprache sind.

    Ganz nebenbei, waere sonst ein Standard C _kein_ gueltiges Standard C++
    Programm (was natuerlich nicht immer so ist).

    Wie Bashar schon sagte, passiert, wenn man einwenig aufpasst und sich gedanken
    macht, eigentlich sehr wenig beim Einsatz von Zeigern.

    mfg
    v R



  • Das setzt den Zeiger auf Null, aber zerstört nicht notwendigerweise das dahinterliegende Objekt.

    Sorry, bin noch nicht ganz wach. Vergesst den Teil meiner Nachrnicht.



  • rafa schrieb:

    Ist also auch in OBERON Zeigerarithmetik möglich? (Google ergab interessante Hinweise.)

    Oberon als Produkt der Familienlinie Modula2 und Modula3 kennt auch den POINTER TO.

    Es ist aber vielleicht falsch, hierzu Zeigerarithmetik zu sagen... solche Dinge wie Zeiger = Zeiger + 3 wie in C und C++ sind nicht so oft erlaubt.

    Allgemein muß ich sowieso bei diesen Diskussionen was sagen: ich höre immer wieder als Gegenargument zu C++, daß man wg. den Zeigern aufpassen muß oder wegen Speicherlöchern.

    Aber nach meiner bisherigen Erfahrung sind dies in unseren Projekten die seltensten Fehlerquellen. Manchmal sind dangling pointer im Zusammenhang mit der Zerstörung von Threads in der Tat Grund zum Stirnrunzeln gewesen, aber das war eher ärgerlich aber leicht zu finden. Deadlocks sind ebenfalls von Zeit zu Zeit Quelle von Ärgernis.

    Am häufigsten kommen so Dinger vor, daß ein Eventhandler mit dem falschen Knopf verlinkt ist oder gar nicht, oder daß irgendwas mal zu früh aufgerufen wird und keiner auf mögliche Exceptions geachtet hat, etc. Fehler wirken sich bei uns eher in "Nichtfunktion" einer Aktion aus. Aber nicht in einem Absturz.

    Nur hört man ja oft, daß in C++ sichere Programme ohne Abstürze aus heiterem Himmel gar nicht möglich sind, nur kann ich diese Aussage nicht mit meiner Erfahrung in Deckung bringen.



  • Was hindert den unerfahrenen Programmierer daran Zeiger nur wie Referenzen einzusetzen( es gibt auch `echte' referenzen in C++) ? und wenn selbst dann noch probleme mit dem speicher herrschen gibt es immernoch garbage collectoren fuer c++. aber wieso sollte man zeiger nicht in der sprache haben und damit erfahrenen programmierern die moeglichkeit zur effizienten programmierung nehmen?



  • thomas001 schrieb:

    Was hindert den unerfahrenen Programmierer daran Zeiger nur wie Referenzen einzusetzen ... aber wieso sollte man zeiger nicht in der sprache haben und damit erfahrenen programmierern die moeglichkeit zur effizienten programmierung nehmen?

    Naja, schöne Idee, aber didaktisch gefährlich, da der typische Mensch leider weder weise noch klug ist.

    Dieser Ansatz hat leider den Schönheitsfehler, daß man einem Kind einen riesigen Werkzeugkasten hinstellt, und sagt: "nicht mit den spitzen Sachen spielen, das ist für Erwachsene". Aus dem gleichen Grund gibt's auch Wohnungsbrände.

    Jeder Ansatz, der für eine Applikation, ein Tool oder eine Sprache Vernunft, Ruhe und Weisheit vom Benutzer erfordert, wird scheitern.

    😉



  • Marc++us schrieb:

    Jeder Ansatz, der für eine Applikation, ein Tool oder eine Sprache Vernunft, Ruhe und Weisheit vom Benutzer erfordert, wird scheitern.
    😉

    Hmmmmm - jetzt weiß ich endlich, warum so viele Software-Projekte (unabhängig von der Programmiersprache) scheitern. Sie alle fordern Vernunft, Ruhe und Weisheit vom Benutzer. Oder etwa nicht? 😉

    Stefan.



  • Marc++us schrieb:

    Allgemein muß ich sowieso bei diesen Diskussionen was sagen: ich höre immer wieder als Gegenargument zu C++, daß man wg. den Zeigern aufpassen muß oder wegen Speicherlöchern.

    Aber nach meiner bisherigen Erfahrung sind dies in unseren Projekten die seltensten Fehlerquellen. Manchmal sind dangling pointer im Zusammenhang mit der Zerstörung von Threads in der Tat Grund zum Stirnrunzeln gewesen, aber das war eher ärgerlich aber leicht zu finden. Deadlocks sind ebenfalls von Zeit zu Zeit Quelle von Ärgernis.

    Am häufigsten kommen so Dinger vor, daß ein Eventhandler mit dem falschen Knopf verlinkt ist oder gar nicht, oder daß irgendwas mal zu früh aufgerufen wird und keiner auf mögliche Exceptions geachtet hat, etc. Fehler wirken sich bei uns eher in "Nichtfunktion" einer Aktion aus. Aber nicht in einem Absturz.

    Nur hört man ja oft, daß in C++ sichere Programme ohne Abstürze aus heiterem Himmel gar nicht möglich sind, nur kann ich diese Aussage nicht mit meiner Erfahrung in Deckung bringen.

    Dem kann ich nur zustimmen!
    Und ergänze eine rethorische Frage: Für *wen* sind solche Fehler "eher ärgerlich aber leicht zu finden"? Eben nicht für die, die Pointer(-arithmetik) für des Teufels vorletzten Streich gegen die Christenheit halten. Weil sie sie halt nicht beherrschen.

    Stefan.



  • Erstmal danke an alle. Das war sehr aufschlußreich.

    PASCAL / OBERON: Es ist für wahr: PASCAL kennt den Pointer. Und das ist erschreckend, denn bisher bin ich nicht darauf gestoßen. Eigenartig. Wie auch immer, eine interessante Erweiterung muss ich sagen.

    CHEFENTWICKLER: Immerhin mein Mentor, hat sich hierin geirrt. Was ihm sicherlich nicht schmeckt. Besser noch, er leugnt es gesagt zu haben, dass PASCAL keine Zeiger kennt. Zitat: 'Ich sagte, in PASCAL werden Zeiger kaum genutzt.' Da ich allerdings im vollen Besitz meiner geistigen Kräfte bin und nur unwesentlich unter Hör- sowie Gedächtnisproblemen leide 🙄, bin ich überrascht, da er es nun leugnet. Aber, das ist wohl ein anderes Thema. (Vermutlich ist es ihm unangenehm.)

    Nun habe ich in mühevoller Arbeit das M&T-Verlag 'C/C++ Kompendium' mit fast 1300 Seiten durchgearbeitet, der nächste 1000-Seiten-Schinken wartet schon. Gut manche Bereiche habe ich überflogen, da Programmiersprachen gewisse Dinge doch gemeinsam haben. Aber ich bin über Zeiger positiv überrascht. Nicht alle Bereiche erscheinen mir zurzeit schlüssig, aber vielleicht braucht es hier noch der praktischen Anwendung. Meine anfängliche Ablehnung und Skepsis habe ich zumindest abgelegt. (Nicht zu unterschätzen der 'A-H-A'-Effekt bei bereits bekannten Methoden, welche sich in C++ als Zeiger entpuppen.) 😋

    Dank an alle.

    Info: Sollte jemand gute Bücher zu C++ (insb. VC++ und Win32-GUI ohne MFC)kennen, möge er mir bitte schreiben (sicher gibt es hier aber genug Threads zu). Ich bin für hilfreiche Bücher stets dankbar (bitte keine Einsteigerbücher wie 'Schritt für Schritt' oder 'for Dummies' mit hunderten von Seiten über Entwicklungsumgebungsbeschreibungen - tolles Wort).

    🙂



  • Hm, diese Zeigerdiskusion hab ich in der Firma mit meinem Vorgesetzten auch führen müssen.

    Er fand Zeiger sehr gefährlich und sie wurden schlicht weg verboten.

    Er schrieb dann sinngemäß eine Funktion

    T * foo()
    {
      T t;
      return &t;
    }
    

    um in

    T & foo()
    {
      T t;
      return t;
    }
    

    und war nun fest davon Überzeugt das dies nun sicher wäre da kein Zeiger verwendet wird.

    Die 'Garbage Collector' führten bei uns in der Praxis zu Quellcode der ähnlich wie diesem hier aussah:

    public sub foo()
    
    myObjekt.test() ' Frage ob ich schon tot bin
    [..]
    myObjekt.test() ' Wieder die Frage ob die software lebt
    [..]
    myObjekt.test() ' Irgendwie hat die Software ein Problem mit der Zukunft :clown:
    
    end sub
    

    Die Kommentare im Quelltext sind zwar aufmunternd, aber nich die Wartungsarbeit die dahintersteht.



  • rafa schrieb:

    Es ist für wahr: PASCAL kennt den Pointer. Und das ist erschreckend

    Das ist hoffentlich ein Scherz. Ohne Zeiger könntest du in Pascal keine dynamischen, rekursiven Datenstrukturen wie Bäume oder Listen aufbauen.



  • @Bashar: Mein Schwerpunkt lag bisher in Visual Basic 6 / 7 und da gibt es 'standardmäßig' (sieht man mal von WinAPI-Umwegen und ASM-Addon ab) keine Zeiger (dafür Referenzen), dennoch habe ich sehr wohl Bäume, Listen und rekursive Strukturen erstellt. Es geht bis zu einem gewissen Grad auch ohne Referenzen und Zeiger, nur ist es langsamer. - PASCAL und DELPHI nutzte ich in anderen Bereichen, wo Zeiger nicht aufkamen (bzw. ich die Notwendigkeit bisher nicht sah).

    Ergänzend: Wie gesagt, vieles (sehr vieles) geht mit und ohne Zeiger.



  • rafa schrieb:

    Es geht bis zu einem gewissen Grad auch ohne Referenzen und Zeiger, nur ist es langsamer.

    klick & bunti kann jeder .. 😋 effizienz ist das A und O beim programmieren



  • 1ntrud0r: Da stimme ich Dir zu. Nur lassen wir mal eine mögliche (sich anbannende) Diskussion über Visual Basic vs. C++. 😉 Ergänzend: Das 'A und O' der Programmierung ist Projektzeit und Effizienz denke ich, daher VB mit C++ (bei uns im Unternehmen).



  • rafa: "Referenzen" und Zeiger sind in dem Zusammenhang relativ gleichwertig. Ich würde nur das Wort "Referenz" in diesem Forum gern vermeiden, wenn ich von anderen Referenzen als C++-Referenzen spreche (diese sind nämlich nicht gleichwertig zu Zeigern).
    Ausserdem vergißt du, dass Pascal auch keine "Referenzen" hat.



  • Gut, vielleicht bist Du in PASCAL / DELPHI mehr fit als ich (wovon ich ausgehe), aber wie sieht es mit der function(var x: integer) aus? Wie in VB mit ByRef und ByVal, nicht? (Aber ich mag mich irren.)

    http://www.informatik.fh-muenchen.de/~schieder/programmieren-1-ws95-96/stack-beispiel.html

    Ergänzend: Der Begriff 'Referenz' im Zusammenhang mit Zeigern (und sogar Arrays) ist mir erst durch C++ klar geworden, daher stimme ich mit Dir absolut überein. (Obige Äußerung von Dir.)



  • Ich kenne VAR, aber das ist natürlich kein Datentyp, und ausserdem eher mit C++-Referenzen als mit "Referenzen" im Sinne von Java, C# oder VB (sofern ich dein "keine Zeiger (dafür Referenzen)" richtig verstanden habe) zu vergleichen. Ich mach mal eine verkettete Liste in einer Sprache, die Pointer hat, und in einer, die "Referenzen" hat.

    // mit Pointern:
    struct Node { int data; Node * next; };
    void output_list(Node * np) { 
      while (np) {
        cout << np->data << endl; 
        np = np->next;
      }
    }
    
    // mit "Referenzen"
    // Achtung: Kein C++ mehr, das ist jetzt Pseudo-Code, eher Java-ähnlich
    struct Node { int data; Node next; }
    void output_list(Node theNode) { 
      while (theNode != null) {
        print(theNode.data);
        theNode = theNode.next;
      }
    }
    

    Du siehst, es ist prinzipiell egal, ob man C/C++-mäßige Pointer oder Java-mäßige Referenzen hat (deshalb nenn ich gerne beides einfach nur Pointer, wenn grad keiner guckt), aber man braucht sowas in jeder imperativen Sprache. Pascal hat letzteres nicht -- wenn es auch keine Pointer hätte, wär es als Allzweckprogrammiersprache völlig ungeeignet (es hat natürlich welche.)


Anmelden zum Antworten