Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » FAQ C / C++ (ANSI-Standard) » ++i und i++

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
07.12.2002, 22:29 Uhr
virtual
Sexiest Bit alive
(Operator)


Was ist der Unterschied zwischen ++i und i++

i++ ("Postfix Inkrement Operator") und ++i ("Präfix Inkrement Operator") machen eigntlich recht Ähnliches: sie erhöhen die Variable i um eins. So schreibt folgende Schleife genauso die zahlen von 1 bis 10 ...

C++:
for(int i=1; i<=10; [b]i++[/b]) std::cout << i << std::endl;


... wie diese hier:

C++:
for(int i=1; i<=10; [b]++i[/b]) std::cout << i << std::endl;


Der Unterschied wird erst deutlich, wenn man die for-Schleife durch eine while-Schleife wie folgt ersetzt:

C++:
int i=1;
while (i<=10) std::cout << [b]i++[/b] << std::endl;


gibt auch 1 bis 10 aus, aber:

C++:
int i=1;
while (i<=10) std::cout << [b]++i[/b] << std::endl;


gibt die Zahlen 2 bis 11 aus. Wie kommt das?

Jeder Ausdruck in C hat ein wertmäßiges Ergebnis und 0-N Nebeneffekte. Die Ausdrücke "i++" und "++i" haben beide den gleichen Nebeneffekt: sie erhöhen i um 1. Allerdings ist ihr wertmäßiges Ergebnis (also das, was hier ausgegeben wird), unterschiedlich: i++ gibt den Wert von i vor der Erhöhung zurück, ++i gibt den Wert von i nach der Erhöhung zurück..
In vielen Fällen ist man lediglich nur an dem Nebeneffekt interessiert, also daß i um eins erhöht wird, wogegen das wertmäßige Ergebnis nicht von interesse ist. Die beiden for-Schleifen am Anfang sind ein Beispiel dafür: Uns interessiert nur, daß i irgendwie um eins nach oben gezählt wird; aber uns interessiert eigentlich nicht so sehr, wie das wertmäßige Ergebnis ist, dieses berücksichtigen wir nicht.
Im Gegensatz dazu wurden bei den while-Schleifen das wertmäßige Ergebnis berücksichtigt, weil es ausgegeben wurde; somit kommen die unterschiedlichen Resultate raus.
Das führt uns direkt zur nächsten Frage:

Was ist "besser": ++i oder i++

Wenn das wertmäßige Ergebnis nicht von Interesse ist, wie zB bei der for-Schleife oben, stellt sich die Frage, was denn nun besser ist: ++i oder i++?
In den meisten älteren C Sourcen findet man tendenziell mehr i++ als ++i for Schleifen, was zu der Annahme verleiten kann, daß es grundsätzlich besser ist, i++ zu verwenden. Dem ist aber nicht so:
In C kann ++i eigentlich nur dann angewendet werden, wenn i ein eingebauter Datentyp wie zB char, int, long, usw. ist. Für diese Typen macht es eigentlich keinen großen Unterschied.
In C++ aber macht es einen Unterschied, weil man dort diese Operatoren "überladen", also für eigene Klassen neu definieren kann. Folgende Nn-Sense Klasse soll den Interschied zwischen i++ und ++i verdeutlichen: Wir definieren die Klasse SI, welche ein Integer in String Form sei und definieren die entsprechenden Operatoren. Zunächst schauen wir und die Deklaration an:

C++:
class SI // StringInteger
{
    std::string str;
    // ...
    SI& operator ++ (); // Deklaration prefix inkrement
    SI operator ++ (int); // Deklaration postfix inkrement
};


Man erkennt bereits an der Deklaration den Unterschied: Das Präfix-Inkrement gibt eine Referenz zurück (erkennbar am "&" im Rückgabetyp), das Postfix-Inkrement ein temp. Objekt. De Implementierung macht auch deutlich, warum dem so ist. Zuerst das Präfix-Inkrement:

C++:
// Präfix inkrement bedeutet: erhöhe den Wert des Objektes um eins (Nebeneffekt)
// und gebe diesen erhöhten Wert zurück (Wertmäßiges Ergebnis). Also
// entspreicht das wertmäßige Ergebnis dem Wert des Objektes nach
// Abarbeitung des Operators
SI& SI::operator ++ ()
{
    // Irgendwie zählen wir den Wert um eins hoch.
    int n;
    std::stringstream stream(str);
    str >> n;

    n = n+1;

    stream.str("");
    stream << n;
    str = stream.str();

    return *this;
}


Aber der Postfix operator sieht doch was anders aus:

C++:
// Postfix inkrement bedeutet: erhöhe den Wert des Objektes um eins (Nebeneffekt)
// und gebe den Wert von Vor der Erhöhung zurück (Wertmäßiges Ergebnis).
// Also entspricht das wertmäßige Ergebnis dem Wert des Objektes vor
// abarbeitung des Operators
SI SI::operator ++ (int)
{
    SI Kopie(*this) ; // Wir merken uns den alten wert des Objekts.
                        
    ++(*this); // Wir inkrementieren genau wie beim Präfix Operator ....

    return Kopie; // Geben aber die Kopie des alten werts zurück
}


Mithin muß also von dem Objekt als zusätzliche Aktion ein Konstruktor und ein Destructor Aufruf getätigt werden.

Fazit: Rein von der Performance her ist der Präfixoperator dem Postfixoperator vor zu ziehen (also ++i besser als i++). Jedoch gilt diese Aussage nur, wenn zwei Bedingungen erfüllt sind:
1. Man ist nicht am wertmäßigen Ergebnis des Ausdrucks interessiert
2. Es handelt sich nicht um einen eingebauten Datentypen (denn für diese gibt es hinsichtlich Performance idR keinen Unterschied).
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)

Dieser Post wurde am 08.12.2002 um 07:55 Uhr von virtual editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ FAQ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: