Operátory přírůstku a úbytku - Increment and decrement operators

Operátory přírůstku a úbytku jsou unární operátory, které přidávají nebo odčítají jeden, nebo od svého operandu . Obvykle jsou implementovány v imperativních programovacích jazycích . Jazyky podobné C obsahují dvě verze (před a po) každého operátora s mírně odlišnou sémantikou.

V jazycích syntakticky odvozených z B (včetně C a jeho různých derivátů) je operátor přírůstku zapsán jako ++a operátor snižování je zapsán jako --. Několik dalších jazyků používá funkce inc (x) a dec (x).

Operátor přírůstku se zvyšuje a operátor snižování snižuje hodnotu jeho operandu o 1. Operand musí mít aritmetický datový typ nebo ukazatel a musí odkazovat na upravitelný datový objekt . Hodnoty ukazatelů se zvýší (nebo sníží) o částku, která je přiměje ukázat na další (nebo předchozí) prvek sousedící s pamětí.

V jazycích, které podporují obě verze operátorů:

  • Předem -increment a předem -decrement operátoři zvýšení (nebo dekrementace) jejich operand o 1, a hodnota výrazu je inkrementován (nebo sníží) hodnota vyplývající.
  • Po -increment a po -decrement operátoři zvýšení (nebo snížení) hodnotu svého operandu o 1, ale hodnota výrazu je hodnota operandu je před k operaci zvýšení (nebo úbytku).

V jazycích, kde přírůstek/úbytek není výrazem (např. Go ), stačí pouze jedna verze (v případě Go pouze operátory příspěvků).

Protože operátor přírůstku/úbytku upravuje svůj operand, použití takového operandu více než jednou v rámci stejného výrazu může vést k nedefinovaným výsledkům. Například ve výrazech, jako x - ++xje, není jasné, v jakém pořadí by měly být prováděny operace odčítání a přírůstku. Takové výrazy obecně vyvolávají nedefinované chování a je třeba se jim vyhnout.

V jazycích se zadanými ukazateli, jako je C, operátor přírůstku přeskočí ukazatel na další položku tohoto typu - zvýší hodnotu ukazatele o velikost tohoto typu. Když ukazatel (správného typu) ukazuje na libovolnou položku v poli, zvýšení (nebo snížení) způsobí, že ukazatel ukáže na položku „další“ (nebo „předchozí“) tohoto pole. Když má ukazatel typ ukazatele na celé číslo, zvyšuje se tím, že ukazatel ukazuje na další celé číslo (obvykle se zvyšuje o 4 bajty). Když ukazatel má typ ukazatel na zaměstnance, inkrementace tohoto ukazatele ukazuje na dalšího „zaměstnance“-pokud je velikost struktury zaměstnance 106 bytů, inkrementace tohoto ukazatele ji zvýší o 106 bytů.

Příklady

Následující fragment kódu C ilustruje rozdíl mezi operátory před a po inkrementaci a dekrementaci:

int x;
int y;

// Increment operators
// Pre-increment: x is incremented by 1, then y is assigned the value of x
x = 1;
y = ++x;    // x is now 2, y is also 2

// Post-increment: y is assigned the value of x, then x is incremented by 1
x = 1;
y = x++;    // y is 1, x is now 2

// Decrement operators
// Pre-decrement: x is decremented by 1, then y is assigned the value of x
x = 1;
y = --x;    // x is now 0, y is also 0

// Post-decrement: y is assigned the value of x, then x is decremented by 1
x = 1;
y = x--;    // y is 1, x is now 0

V jazycích bez těchto operátorů vyžadují ekvivalentní výsledky další řádek kódu:

# Pre-increment: y = ++x
x = 1
x = x + 1  # x is now 2  (can be written as "x += 1" in Python)
y = x      # y is also 2

# Post-increment: y = x++
x = 1
y = x      # y is 1
x = x + 1  # x is now 2


Operátor po přírůstku se běžně používá s předplatnými pole . Například:

// Sum the elements of an array
float sum_elements(float arr[], int n)
{
    float  sum = 0.0;
    int    i =   0;

    while (i < n)
        sum += arr[i++];    // Post-increment of i, which steps
                            //  through n elements of the array
    return sum;
}

Operátor po přírůstku se také běžně používá s ukazateli :

// Copy one array to another
void copy_array(float *src, float *dst, int n)
{
    while (n-- > 0)        // Loop that counts down from n to zero
        *dst++ = *src++;   // Copies element *(src) to *(dst),
                           //  then increments both pointers
}

Tyto příklady fungují také v jiných jazycích podobných C , jako je C ++ , Java a C# .

  • Přírůstkový operátor lze demonstrovat na příkladu:
    #include <stdio.h>
    int main()
    {
        int c=2;
        printf("%d\n", c++); // this statement displays 2, then c is incremented by 1 to 3.
        printf("%d", ++c);   // this statement increments c by 1, then c is displayed.
        return 0;
    }
    
    • Výstup:
      2
      4
      

Podpůrné jazyky

Následující seznam, i když není úplný nebo úplný, uvádí některé z hlavních programovacích jazyků, které podporují operátory ++/ --přírůstek / úbytek.

(Apple Swift kdysi podporoval tyto operátory, ale podpora byla od verze 3 odstraněna.)

Pascal , Delphi , Modula-2 a Oberon poskytují stejné funkce, ale nazývají se inc (x) a dec (x).

Zejména Python a Rust tyto operátory nepodporují.

Dějiny

Koncept byl představen v programovacím jazyce B kolem roku 1969 Kenem Thompsonem .

Thompson šel o krok dále tím, že vynalezl operátory ++ a -, které zvyšují nebo snižují; jejich poloha předpony nebo postfixu určuje, zda ke změně dojde před nebo po zaznamenání hodnoty operandu. Nebyli v nejranějších verzích B, ale objevovali se po cestě. Lidé často hádají, že byly vytvořeny pro použití režimů automatického přírůstku a automatického snižování adres poskytovaných DEC PDP-11, ve kterém se C a Unix poprvé staly populární. To je historicky nemožné, protože při vývoji B neexistoval PDP-11. PDP-7 však měl několik paměťových buněk s „automatickým přírůstkem“, přičemž vlastnost, že prostřednictvím nich nepřímá paměťová reference buňku zvětšila. Tato funkce pravděpodobně navrhla takové operátory společnosti Thompson; zobecnění, které z nich udělalo prefix i postfix, bylo jeho vlastní. Buňky s automatickým přírůstkem nebyly skutečně použity přímo při implementaci operátorů a silnější motivací pro inovaci bylo pravděpodobně jeho zjištění, že překlad ++ x byl menší než překlad x = x+1.

Viz také

Reference