Achtergrond:
De incremente operateurs ++ en decremente -- zijn ontstaan in de vroegste versies van C en zijn geïnspireerd door de mogelijkheden van low-level machinetaal. Prefix vormen (++i, --i) en postfix vormen (i++, i--) bieden programmeurs verschillende semantieken met minimale computatiekosten.
Probleem:
De belangrijkste moeilijkheid is dat prefix en postfix vormen zich anders gedragen: de prefixvorm verhoogt/verlaagt eerst de waarde en geeft dan het resultaat terug, terwijl de postfixvorm eerst de oorspronkelijke waarde teruggeeft en daarna de variabele wijzigt. In geneste uitdrukkingen leidt dit vaak tot verwarring, onverwacht gedrag en onjuist gebruik van waarde.
Oplossing:
Het is belangrijk duidelijk te maken wat elke vorm retourneert. De prefixversie wordt gebruikt wanneer je onmiddellijk de nieuwe waarde wilt krijgen. De postfixvorm wanneer het belangrijk is om de oude waarde te behouden (bijvoorbeeld om door te geven aan een functie of voor tel-logica). Goede praktijk is om complexe uitdrukkingen met meerdere incremente te vermijden en het gebruik met bijeffecten niet te mengen.
Voorbeeldcode:
int i = 5; printf("%d\n", ++i); // Geeft 6 weer printf("%d\n", i++); // Geeft 6 weer, maar nu is i 7
Belangrijke kenmerken:
Is het mogelijk om i = i++ te gebruiken en wat gebeurt er?
Het gebruik van de constructie i = i++ leidt tot onbepaald gedrag: de compiler is niet verplicht om het verwachte resultaat te garanderen, en de programma kan zich onvoorspelbaar gedragen.
Voorbeeldcode:
int i = 1; i = i++; printf("%d\n", i); // Resultaat hangt af van de compiler: kan 1 of 2 zijn
Waarom is het gevaarlijk om incremente in één regel met meerdere gebruik van dezelfde variabele te gebruiken?
Bij meerdere veranderingen van dezelfde variabele in één uitdrukking (bijvoorbeeld f(i++, i++)) is het gedrag niet gedefinieerd volgens de C-standaard. Het uiteindelijke resultaat hangt af van de specifieke implementatie van de compiler.
Is i++ altijd sneller dan ++i?
Nee. Bij moderne compilers is er meestal geen verschil, omdat de compiler beide vormen gelijkmatig optimaliseert, tenzij de geretourneerde waarde van de uitdrukking zelf wordt gebruikt.
In een lus heeft de ontwikkelaar geschreven:
for (int i = 0; i < 10;) arr[i] = i++ * 2;
Voordelen:
Nadelen:
for (int i = 0; i < 10; i++) arr[i] = i * 2;
Voordelen:
Nadelen: