Atualmente estou aprendendo C ++ e aprendi sobre incrementação há um tempo. Eu sei que você pode usar "++ x" para fazer a incrementação antes e "x ++" para fazer depois.
Ainda assim, eu realmente não sei quando usar nenhum dos dois ... Eu nunca usei "++ x" e as coisas sempre funcionaram bem até agora - então, quando devo usá-lo?
Exemplo: Em um loop for, quando é preferível usar "++ x"?
Além disso, alguém poderia explicar exatamente como funcionam as diferentes incrementações (ou decrementações)? Eu realmente apreciaria isto.
fonte
x++
é um rvalue com o valor dex
antes do incremento,x++
é um lvalue com o valor dex
depois de um incremento. Nenhuma das expressões garante quando o valor real incrementado é armazenado de volta para x, só é garantido que isso aconteça antes do próximo ponto de sequência. 'após o processamento da instrução atual' não é estritamente preciso, pois algumas expressões têm pontos de sequência e algumas instruções são instruções compostas.Scott Meyers diz para você preferir prefixo, exceto nas ocasiões em que a lógica ditaria que o pós-fixo é apropriado.
Item 6 do "C ++ Mais Eficaz" - é autoridade suficiente para mim.
Para quem não possui o livro, aqui estão as citações pertinentes. Da página 32:
E na página 34:
fonte
i++
ou++i
, o código gerado é o mesmo.++x
ex++
realmente importa, é muito mais importante que você realmente use um compilador que possa otimizar completa e adequadamente qualquer versão, não importa qual contexto. "Já que estou usando este martelo velho de baixa qualidade, só posso cravar os pregos em um ângulo de 43,7 graus" é um argumento fraco para construir uma casa enfiando os pregos a apenas 43,7 graus. Use uma ferramenta melhor.De cppreference ao incrementar iteradores:
O pré-incremento não gera o objeto temporário. Isso pode fazer uma diferença significativa se o seu objeto for caro para criar.
fonte
Eu só quero notar que o código gerado é frequentemente o mesmo se você usar pré / pós-incremento onde a semântica (de pré / pós) não importa.
exemplo:
pre.cpp:
post.cpp:
_
fonte
std::map::iterator
? Claro que os dois operadores são diferentes, mas estou curioso para saber se o compilador otimizará postfix para prefix se o resultado não for usado. Não acho que seja permitido - visto que a versão pós-fixada pode conter efeitos colaterais.O mais importante a se ter em mente, imo, é que x ++ precisa retornar o valor antes que o incremento realmente ocorra - portanto, ele deve fazer uma cópia temporária do objeto (pré-incremento). Isso é menos eficiente do que ++ x, que é incrementado no local e retornado.
Outra coisa que vale a pena mencionar, entretanto, é que a maioria dos compiladores serão capazes de otimizar essas coisas desnecessárias quando possível, por exemplo, ambas as opções levarão ao mesmo código aqui:
fonte
Eu concordo com @BeowulfOF, embora, para maior clareza, eu sempre defendesse a divisão das declarações para que a lógica fosse absolutamente clara, ou seja:
ou
Portanto, minha resposta é: se você escrever um código claro, isso raramente importará (e se for importante, seu código provavelmente não é claro o suficiente).
fonte
Só queria enfatizar novamente que se espera que ++ x seja mais rápido que x ++, (especialmente se x for um objeto de algum tipo arbitrário), portanto, a menos que seja necessário por razões lógicas, ++ x deve ser usado.
fonte
Você explicou a diferença corretamente. Depende apenas se você deseja que x seja incrementado antes de cada execução em um loop, ou depois disso. Depende da lógica do seu programa, o que é apropriado.
Uma diferença importante ao lidar com Iteradores STL (que também implementam esses operadores) é que ++ cria uma cópia do objeto para o qual o iterador aponta, a seguir incrementa e retorna a cópia. ++ ele, por outro lado, faz o incremento primeiro e depois retorna uma referência ao objeto para o qual o iterador agora aponta. Isso é principalmente relevante apenas quando cada bit de desempenho conta ou quando você implementa seu próprio iterador de STL.
Editar: corrigiu a confusão de notação de prefixo e sufixo
fonte
Exemplo 1:
Quando vários valores são colocados em cascata com << usando cout , os cálculos (se houver) ocorrem da direita para a esquerda, mas a impressão ocorre da esquerda para a direita, por exemplo, (se val se inicialmente 10)
resultará em
Exemplo 2:
No Turbo C ++, se múltiplas ocorrências de ++ ou (em qualquer forma) são encontradas em uma expressão, então primeiro todas as formas de prefixo são calculadas, então a expressão é avaliada e finalmente as formas pós-fixadas são calculadas, por exemplo,
Sua saída em Turbo C ++ será
Considerando que sua saída no compilador moderno será (porque eles seguem as regras estritamente)
expressões variam de compilador para compilador.
fonte
Compreender a sintaxe da linguagem é importante ao considerar a clareza do código. Considere copiar uma sequência de caracteres, por exemplo, com pós-incremento:
Queremos que o loop seja executado encontrando o caractere zero (que é falso) no final da string. Isso requer o teste do pré-incremento do valor e também o incremento do índice. Mas não necessariamente nessa ordem - uma maneira de codificar isso com o pré-incremento seria:
É uma questão de gosto o que fica mais claro e se a máquina tem um punhado de registradores, ambos devem ter tempos de execução idênticos, mesmo que a [i] seja uma função cara ou tenha efeitos colaterais. Uma diferença significativa pode ser o valor de saída do índice.
fonte