Operadores de incremento e decremento - Increment and decrement operators

Incremento e operadores decremento são unários operadores que adicionar ou subtrair um, ou de seu operando , respectivamente. Eles são comumente implementados em linguagens de programação imperativas . As linguagens semelhantes a C apresentam duas versões (pré e pós) de cada operador com semânticas ligeiramente diferentes.

Em linguagens derivadas sintaticamente de B (incluindo C e seus vários derivados), o operador de incremento é escrito como ++e o operador de decremento é escrito como --. Várias outras linguagens usam funções inc (x) e dec (x).

O operador de incremento aumenta e o operador de decremento diminui o valor de seu operando em 1. O operando deve ter um tipo de dados aritmético ou de ponteiro e deve referir-se a um objeto de dados modificável . Os valores dos ponteiros são aumentados (ou diminuídos) em uma quantidade que os faz apontar para o próximo (ou anterior) elemento adjacente na memória.

Em idiomas que suportam ambas as versões dos operadores:

  • Os operadores de pré- incremento e pré- decremento incrementam (ou decrementam) seu operando em 1, e o valor da expressão é o valor incrementado (ou decrementado) resultante.
  • Os operadores pós- incremento e pós- decremento aumentam (ou diminuem) o valor de seu operando em 1, mas o valor da expressão é o valor do operando antes da operação de incremento (ou decremento).

Em linguagens em que incremento / decremento não é uma expressão (por exemplo, Go ), apenas uma versão é necessária (no caso de Go, apenas operadores de postagem).

Como o operador de incremento / decremento modifica seu operando, o uso de tal operando mais de uma vez na mesma expressão pode produzir resultados indefinidos. Por exemplo, em expressões como x - ++x, não está claro em que sequência as operações de subtração e incremento devem ser realizadas. Essas expressões geralmente invocam um comportamento indefinido e devem ser evitadas.

Em linguagens com ponteiros digitados como C, o operador de incremento avança o ponteiro para o próximo item daquele tipo - aumentando o valor do ponteiro pelo tamanho daquele tipo. Quando um ponteiro (do tipo correto) aponta para qualquer item em uma matriz, incrementar (ou decrementar) faz com que o ponteiro aponte para o "próximo" (ou "anterior") item dessa matriz. Quando um ponteiro tem um tipo de ponteiro para inteiro, incrementar esse ponteiro faz com que ele aponte para o próximo inteiro (normalmente aumentando em 4 bytes). Quando um ponteiro tem um tipo de ponteiro para funcionário, incrementar esse ponteiro faz com que ele aponte para o próximo "funcionário" - se o tamanho da estrutura do funcionário for de 106 bytes, incrementar esse ponteiro aumenta em 106 bytes.

Exemplos

O seguinte fragmento de código C ilustra a diferença entre os operadores pré e pós incremento e decremento:

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

Em linguagens sem esses operadores, resultados equivalentes requerem uma linha extra de código:

# 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


O operador pós-incremento é comumente usado com subscritos de array . Por exemplo:

// 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;
}

O operador pós-incremento também é comumente usado com ponteiros :

// 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
}

Observe que esses exemplos também funcionam em outras linguagens semelhantes a C , como C ++ , Java e C # .

  • O operador de incremento pode ser demonstrado por um exemplo:
    #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;
    }
    
    • Saída:
      2
      4
      

Idiomas de apoio

A lista a seguir, embora não seja completa ou abrangente, lista algumas das principais linguagens de programação que oferecem suporte aos operadores ++/ --incremento / decremento.

(O Swift da Apple já suportava esses operadores, mas o suporte foi removido a partir da versão 3.)

Pascal , Delphi , Modula-2 e Oberon fornecem as mesmas funções, mas são chamadas de inc (x) e dec (x).

Notavelmente, Python e Rust não oferecem suporte a esses operadores.

História

O conceito foi introduzido na linguagem de programação B por volta de 1969 por Ken Thompson .

Thompson deu um passo adiante ao inventar os operadores ++ e -, que aumentam ou diminuem; sua posição de prefixo ou pós-fixação determina se a alteração ocorre antes ou depois de notar o valor do operando. Eles não estavam nas primeiras versões de B, mas apareceram ao longo do caminho. As pessoas freqüentemente acham que eles foram criados para usar os modos de endereço de autoincremento e auto-decremento fornecidos pelo DEC PDP-11 no qual C e Unix se tornaram populares pela primeira vez. Isso é historicamente impossível, uma vez que não havia PDP-11 quando B foi desenvolvido. O PDP-7, no entanto, tinha algumas células de memória de 'incremento automático', com a propriedade de que uma referência de memória indireta por meio delas incrementava a célula. Esse recurso provavelmente sugeriu tais operadores a Thompson; a generalização para torná-los prefixo e pós-fixados era sua. De fato, as células de autoincremento não foram usadas diretamente na implementação dos operadores, e uma motivação mais forte para a inovação foi provavelmente sua observação de que a tradução de ++ x era menor que a de x = x + 1.

Veja também

Referências