Wofür i++?



  • Wofür braucht man i++?
    ++i ist schließlich schneller und liefert keine unnütze Kopie. Wenn man i++ erreichen will, dann kann man das doch einfach in zwei Schritten machen:
    int a = i; ++i;
    statt:
    int a = ++i;
    Hier gibt es eine unnütze Kopie. Wofür also i++?



  • f(i++);
    


  • Die Frage ist was einfacher zu lesen ist, für int sollte die Performance die selbe sein.



  • *iter++ = 0;



  • ++i++ schrieb:

    Wenn man i++ erreichen will, dann kann man das doch einfach in zwei Schritten machen:
    int a = i; ++i;

    ja, aber int a = C; ++C; ist kein so schöner Name für eine Sprache wie C++.


  • Mod

    Postfix Inkrement/Dekrement stammt, wie die restlichen arithmetischen Operatoren, von C. Und über die Praktiken in den 70ern wollen wir gar nicht erst sprechen; damals hatten die Fachleute noch kein sehr gutes Verständnis von sauberem Stil. Die interessantere Frage ist, ob Postfix Operatoren heute noch sinnvoll angewandt werden können, was ich persönlich verneinen möchte: Genau wie das Aneinanderketten von Zuweisungen ist so ein Code i.d.R. unnötig lapidar. Das kann man ruhig ausschreiben, und dann wird die Reihenfolge der Seiteneffekte auch sofort ersichtlich.

    Es gibt allerdings zumindest eine Ausnahme, und das sind die Idiome im Iteratorenmodell.

    template<class InputIt, class OutputIt>
    OutputIt copy(InputIt first, InputIt last, 
                  OutputIt d_first)
    {
        while (first != last) {
            *d_first++ = *first++;
        }
        return d_first;
    }
    

    Abgesehen davon fällt mir nichts ein.



  • Arcoth schrieb:

    Postfix Inkrement/Dekrement stammt, wie die restlichen arithmetischen Operatoren, von C. Und über die Praktiken in den 70ern wollen wir gar nicht erst sprechen; damals hatten die Fachleute noch kein sehr gutes Verständnis von sauberem Stil.

    Wie kommst Du auf diesen Unsinn?



  • template<class InputIt, class OutputIt>
    OutputIt copy(InputIt first, InputIt last,
                  OutputIt d_first)
    {
        while (first != last) {
            *d_first++ = *first++;
        }
        return d_first;
    }
    

    Es gibt allerdings zumindest eine Ausnahme, und das sind die Idiome im Iteratorenmodell.

    Warum sollte das die Ausnahme sein ?

    Das kann man doch genauso umschreiben, und laut deiner Sichtweisse sollte das dann auch leserlicher werden ? oder nicht ?

    warum sind iteratoren Ausnahmen?
    Sie sind doch das generalisierte Konzept von Zeigern auf Daten ...
    Also sollten Zeiger an sich dann auch ne Ausnahme sein ?
    und wenn Zeiger, warum dann nicht der rest der integer Typen ?


  • Mod

    RHBaum schrieb:

    Das kann man doch genauso umschreiben, und laut deiner Sichtweisse sollte das dann auch leserlicher werden ?

    Nein. Für mich ist das *i++ Muster für Iteratoren gang und gäbe, also habe ich keinerlei Schwierigkeiten, es zu lesen. Es ist eine Konvention, an die sich alle gewöhnt haben. Alle anderen solchen Muster.. kenne ich eben nicht. Da bräuchte ich womöglich einen Augenblick, um die Bedeutung des Codes nachzuvollziehen. Und schon da besteht die Möglichkeit, dass ich ihn missverstehe.

    Also sollten Zeiger an sich dann auch ne Ausnahme sein ?

    Zeiger sind Iteratoren.

    und wenn Zeiger, warum dann nicht der rest der integer Typen ?

    Könnte man, klar. In simplen einzeiligen Schleifenkörpern mache ich das auch. Aber es geht hier um einen Grundsatz. Was Werner Salomon für simpel hält, könnte für mich auch komplex sein. In generischem Code, der Iteratoren einsetzt, ist *i++ --und auch nur auf bspw. der linken Seite einer Zuweisung--leicht zu verstehen. Quod licet...

    PS: Hör auf zu plenken.

    Wie kommst Du auf diesen Unsinn?

    Weil zwei der raffiniertesten Köpfe so eine abscheuliche Sprache designed haben? C allein ist Beweis genug. So eine Sprache würde heute niemand mehr kreieren. Algol 68 ist nicht weniger schlimm. OOP war damals auch noch nicht ubiquitär, nur von wenigen Sprachen vertreten, und die Syntax.. es gibt nichts hässlicheres als diese begin/end Lawinen. Auch so etwas ist heute... selten.



  • Arcoth schrieb:

    Wie kommst Du auf diesen Unsinn?

    Weil zwei der raffiniertesten Köpfe so eine abscheuliche Sprache designed haben? C allein ist Beweis genug. So eine Sprache würde heute niemand mehr kreieren. Algol 68 ist nicht weniger schlimm. OOP war damals auch noch nicht ubiquitär, nur von wenigen Sprachen vertreten, und die Syntax.. es gibt nichts hässlicheres als diese begin/end Lawinen. Auch so etwas ist heute... selten.

    Aha. Und daher schließt Du darauf, daß die Fachleute von damals keinen Sinn für sauberen Stil hatten.

    Vielleicht liegt es aber doch eher daran, daß damalige Rechner halt einfach nur nicht die Leistungsfähigkeit hatten, um Sprachen wie C++ in einer vernünftigen Zeit zu überseten. Das vorangige Designziel von C war beispielsweise, eine Sprache zu schaffen, die einfach übersetzt werden konnte. Ich habe jedenfalls 1980 das Programmieren gelernt und mir wurde schon damals eingetrichtert, daß nur mit einem sauberen Stil qualitativ hochwertige Programme möglich sind.

    VG



  • mgaeckler schrieb:

    Ich habe jedenfalls 1980 das Programmieren gelernt und mir wurde schon damals eingetrichtert, daß nur mit einem sauberen Stil qualitativ hochwertige Programme möglich sind.

    Damit widersprichst du Arcoth doch gar nicht - zumindest so wie ich ihn verstanden habe:

    hatten die Fachleute noch kein sehr gutes Verständnis von sauberem Stil

    Nicht der fehlende Wille oder Faulheit oder was auch immer, sondern Verständnis.
    Und das ist ja wohl auch naheliegend, dass das Verständnis mit der Zeit wächst.



  • Arcoth schrieb:

    C allein ist Beweis genug. So eine Sprache würde heute niemand mehr kreieren.

    weil es C ja schon gibt. Und C füllt seine Nische seit über 4 Jahrzehnten sehr gut aus.

    Was würdest du denn konzeptuell - also aus der Vogelperspektive, nicht in syntaktischen Einzelheiten - anders machen, wenn du eine Sprache designen solltest, die genau die Anforderungen von C erfüllt?


  • Mod

    zufallswert schrieb:

    Arcoth schrieb:

    C allein ist Beweis genug. So eine Sprache würde heute niemand mehr kreieren.

    weil es C ja schon gibt. Und C füllt seine Nische seit über 4 Jahrzehnten sehr gut aus.

    Ja, dank einem Monopol. "Sehr gut" ist sicher aus deinem Finger gezogen. Wie viele Menschen wohl schon wegen Bugs in C Code gestorben sind, die mit Sprachen mit formaler Semantik gefunden worden wären? Das ist ein extremer Gegensatz, aber wenn die Zahl signifikant ist, gäbe das zu denken.

    Was würdest du denn konzeptuell - also aus der Vogelperspektive, nicht in syntaktischen Einzelheiten - anders machen, wenn du eine Sprache designen solltest, die genau die Anforderungen von C erfüllt?

    Hast du überhaupt mitbekommen, wovon dieser Thread handelt? Es ging um eine syntaktische Einzelheit. Und die und andere habe ich kritisiert. So wie die Tatsache, dass bitweise Operatoren schwächer binden als relationale. Ich habe gar nicht vor, Designfehler von C zu kritisieren, das haben viele vor mir getan.



  • Arcoth schrieb:

    zufallswert schrieb:

    Arcoth schrieb:

    C allein ist Beweis genug. So eine Sprache würde heute niemand mehr kreieren.

    weil es C ja schon gibt. Und C füllt seine Nische seit über 4 Jahrzehnten sehr gut aus.

    Ja, dank einem Monopol.

    von was für einem Monopol redest du?

    Es gab zur Frühzeit von C mehrere konkurrierende Sprachen mit ähnlichen Fähigkeiten, von BCPL und Algol über Pascal und Bliss bis zur PL/-Sprachengruppe, aber auf Dauer durchgesetzt hat sich C. Das sieht für mich weniger nach Monopol aus als eher nach survival of the fittest.



  • Ich hätte da mal noch ne Verständnisfrage.

    i++
    

    und

    ++i
    

    ist post-decrement und pre-decrement, ok.

    j = j + 5
    

    ist gleichbedeutet wie

    j += 5
    

    , ebenso wie

    j += 1
    

    und

    j++
    

    .

    Wenn ich eine for-Schleife mit

    j += 2
    

    habe, weshalb sollte ich plötzlich

    ++j
    

    schreiben, wenn es statt der 2 eine 1 ist? Warum nicht wie vorher

    j++
    

    ?



  • lemon03 schrieb:

    Ich hätte da mal noch ne Verständnisfrage.

    j = j + 5
    

    ist gleichbedeutet wie

    j += 5
    

    , ebenso wie

    j += 1
    

    und

    j++
    

    .

    Nö, das ist nicht unbedingt gleichbedeutend. Wenn j ein int ist und das einzeln da steht, dann schon, aber nicht im allgemeinen Fall.

    Wenn j ein Objekt, dann tut das eine das, was der operator+= macht und das andere das, was der operator++ macht. Aber mal ganz davon abgesehen, auch für int ist es nicht dasselbe. Insbesondere ist der Rückgabewert unterschiedlich. Beispiel:

    int j = 1;
    auto k = j += 1;
    j = 1;
    auto l = j++;
    std::cout << "k = " << k << ", l = " << l << '\n';
    

    Wie du siehst, kannst du das eine eben nicht einfach durch das andere ersetzen. Wohl aber könntest du das j += 1 hier durch ++j ersetzen.



  • Aha, tatsächlich! Danke.

    Nochmal zurück zu der einfachen for-schleife. Ob ich sie mit i+=1 laufen lasse oder mit i++ dürfte doch aber von der Logik nicht anders ablaufen?

    Falls doch, müssten ja Generationen von for-Schleifen unsinnig sein. Dies scheint aber nicht zu sein, weil sonst ein Haufen Programme gar nicht laufen würden, bzw gelaufen sein können?

    Auch hat es sich erst seit einiger Zeit eingebürgert, einfache for-Schleifen mit ++i zu schreiben. Was hat sich dort geändert?



  • PreIncrement vs. PostIncrement. Was ist wohl der Unterschied?

    http://www.embedded.com/design/programming-languages-and-tools/4410601/Pre-increment-or-post-increment-in-C-C-
    

    Dazu muss man kein Raketenwissenschaftler sein, um das bei Gockel innerhalb einer Sekunde zu finden.



  • Gut, danke. Ich hatte ein Wahrnehmungsproblem. Ich wollte wissen, weshalb man sich irgendwann für diese Schreibweise entschieden hat. Ich habe jetzt aber nochmal rumgeschaut und in fortschrittlichen Code hatte man dies schon immer so gemacht.

    Ich bin also von einer ganz falschen Annahme ausgegangen.


Log in to reply