Diferença entre i ++ e ++ i em um loop?

Existe alguma diferença em ++i e i++ em um loop for ? É simplesmente uma coisa syntax?

um ++ é conhecido como postfix.

adicione 1 a, retorna o valor antigo.

++ a é conhecido como prefixo.

adicione 1 a, retorna o novo valor.

C #:

 string[] items = {"a","b","c","d"}; int i = 0; foreach (string item in items) { Console.WriteLine(++i); } Console.WriteLine(""); i = 0; foreach (string item in items) { Console.WriteLine(i++); } 

Saída:

 1 2 3 4 0 1 2 3 

foreach loops foreach e while dependem de qual tipo de incremento você usa. Com loops for como abaixo, não faz diferença, pois você não está usando o valor de retorno de i:

 for (int i = 0; i < 5; i++) { Console.Write(i);} Console.WriteLine(""); for (int i = 0; i < 5; ++i) { Console.Write(i); } 

0 1 2 3 4
0 1 2 3 4

Se o valor avaliado for usado, o tipo de incremento se tornará significativo:

 int n = 0; for (int i = 0; n < 5; n = i++) { } 

Pré-incremento ++ i aumenta o valor de i e avalia o novo valor incrementado.

 int i = 3; int preIncrementResult = ++i; Assert( preIncrementResult == 4 ); Assert( i == 4 ); 

O pós-incremento i ++ incrementa o valor de i e avalia o valor original não incrementado.

 int i = 3; int postIncrementResult = i++; Assert( postIncrementtResult == 3 ); Assert( i == 4 ); 

Em C ++, o pré-incremento é geralmente preferido onde você pode usar qualquer um deles.

Isso porque, se você usar pós-incremento, poderá exigir que o compilador tenha que gerar código que crie uma variável temporária extra. Isso ocorre porque os valores anterior e novo da variável que está sendo incrementada precisam ser mantidos em algum lugar porque podem ser necessários em outro lugar na expressão que está sendo avaliada.

Portanto, em C ++, pelo menos, pode haver uma diferença de desempenho que orienta a sua escolha de qual usar.

Isso é principalmente apenas um problema quando a variável que está sendo incrementada é um tipo definido pelo usuário com um operador ++ sobreposto. Para tipos primitivos (int, etc) não há diferença de desempenho. Mas, vale a pena manter o operador pré-incremental como uma diretriz, a menos que o operador pós-incremento seja definitivamente o que é necessário.

Há mais algumas discussões aqui:
https://web.archive.org/web/20170405054235/http://en.allexperts.com/q/C-1040/Increment-operators.htm

Em C ++, se você estiver usando o STL, talvez esteja usando loops com iteradores. Estes principalmente substituíram os operadores ++, então aderir ao pré-incremento é uma boa idéia. Os compiladores ficam mais inteligentes o tempo todo, e os mais novos podem executar otimizações que significam que não há diferença de desempenho – especialmente se o tipo que está sendo incrementado é definido em linha no arquivo de header (como as implementações STL são frequentemente) para que o compilador possa ver como O método é implementado e, em seguida, pode saber quais otimizações são seguras para executar. Mesmo assim, provavelmente ainda vale a pena adotar o pré-incremento porque os loops são executados muitas vezes e isso significa que uma pequena penalidade de desempenho pode ser ampliada em breve.


Em outras linguagens como C #, em que o operador ++ não pode ser sobrecarregado, não há diferença de desempenho. Usado em um loop para avançar a variável de loop, os operadores de pré e pós-incremento são equivalentes.

Correção: a sobrecarga ++ em C # é permitida. Parece, porém, que em comparação com C ++, em c # você não pode sobrecarregar as versões pré e pós de forma independente. Então, eu diria que se o resultado de chamar ++ em C # não for atribuído a uma variável ou usado como parte de uma expressão complexa, o compilador reduzirá as versões anteriores e posteriores de ++ para o código que executa equivalentemente.

Em c # não há diferença quando usado em um loop for .

 for (int i = 0; i < 10; i++) { Console.WriteLine(i); } 

produz a mesma coisa que

 for (int i = 0; i < 10; ++i) { Console.WriteLine(i); } 

Como outros apontaram, quando usados ​​em geral, i ++ e ++, eu tenho uma diferença sutil, mas significativa:

 int i = 0; Console.WriteLine(i++); // Prints 0 int j = 0; Console.WriteLine(++j); // Prints 1 

i ++ lê o valor de i, em seguida, incrementa-o.

++ i incrementa o valor de então lê.

Desde que você pergunta sobre a diferença em um loop, eu acho que você quer dizer

 for(int i=0; i<10; i++) ...; 

Nesse caso, você não tem diferença na maioria das linguagens: O loop se comporta da mesma maneira, independentemente de você escrever i++ e ++i . Em C ++, você pode escrever suas próprias versões dos operadores ++, e você pode definir significados separados para eles, se o i for de um tipo definido pelo usuário (sua própria class, por exemplo).

A razão pela qual isso não importa acima é porque você não usa o valor de i++ . Outra coisa é quando você faz

 for(int i=0, a = 0; i<10; a = i++) ...; 

Agora, há uma diferença, porque, como outros apontam, i++ significa incrementar, mas avaliar o valor anterior , mas ++i significa incremento, mas avalie para i (assim, ele seria avaliado para o novo valor). No caso acima, a é atribuído o valor anterior de i, enquanto i é incrementado.

A questão é:

Existe alguma diferença em ++ i e i ++ em um loop for?

A resposta é: não .

Por que cada uma das respostas tem que entrar em explicações detalhadas sobre pré e pós-incremento quando isso não é solicitado?

Este for-loop:

 for (int i = 0; // Initialization i < 5; // Condition i++) // Increment { Output(i); } 

Seria traduzir para este código sem usar loops:

 int i = 0; // Initialization loopStart: if (i < 5) // Condition { Output(i); i++ or ++i; // Increment goto loopStart; } 

Agora importa se você coloca i++ ou ++i no Incremento aqui? Não, não, como o valor de retorno da operação de incremento é insignificante. i serei incrementado após a execução do código que está no for-loop-body.

Como esse código mostra (consulte o MSIL dissambled nos comentários), o compilador C # 3 não faz distinção entre i ++ e ++ i em um loop for. Se o valor de i ++ ou ++ i estivesse sendo obtido, definitivamente haveria uma diferença (isso foi compilado no Visutal Studio 2008 / Release Build):

 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace PreOrPostIncrement { class Program { static int SomethingToIncrement; static void Main(string[] args) { PreIncrement(1000); PostIncrement(1000); Console.WriteLine("SomethingToIncrement={0}", SomethingToIncrement); } static void PreIncrement(int count) { /* .method private hidebysig static void PreIncrement(int32 count) cil managed { // Code size 25 (0x19) .maxstack 2 .locals init ([0] int32 i) IL_0000: ldc.i4.0 IL_0001: stloc.0 IL_0002: br.s IL_0014 IL_0004: ldsfld int32 PreOrPostIncrement.Program::SomethingToIncrement IL_0009: ldc.i4.1 IL_000a: add IL_000b: stsfld int32 PreOrPostIncrement.Program::SomethingToIncrement IL_0010: ldloc.0 IL_0011: ldc.i4.1 IL_0012: add IL_0013: stloc.0 IL_0014: ldloc.0 IL_0015: ldarg.0 IL_0016: blt.s IL_0004 IL_0018: ret } // end of method Program::PreIncrement */ for (int i = 0; i < count; ++i) { ++SomethingToIncrement; } } static void PostIncrement(int count) { /* .method private hidebysig static void PostIncrement(int32 count) cil managed { // Code size 25 (0x19) .maxstack 2 .locals init ([0] int32 i) IL_0000: ldc.i4.0 IL_0001: stloc.0 IL_0002: br.s IL_0014 IL_0004: ldsfld int32 PreOrPostIncrement.Program::SomethingToIncrement IL_0009: ldc.i4.1 IL_000a: add IL_000b: stsfld int32 PreOrPostIncrement.Program::SomethingToIncrement IL_0010: ldloc.0 IL_0011: ldc.i4.1 IL_0012: add IL_0013: stloc.0 IL_0014: ldloc.0 IL_0015: ldarg.0 IL_0016: blt.s IL_0004 IL_0018: ret } // end of method Program::PostIncrement */ for (int i = 0; i < count; i++) { SomethingToIncrement++; } } } } 

Um (++ i) é pré-incremento, um (i ++) é pós-incremento. A diferença está em qual valor é imediatamente retornado da expressão.

 // Psuedocode int i = 0; print i++; // Prints 0 print i; // Prints 1 int j = 0; print ++j; // Prints 1 print j; // Prints 1 

Edit: Woops, ignorou inteiramente o lado do loop das coisas. Não há diferença real nos loops quando é a parte do ‘step’ (para (…; …;)), mas pode entrar em jogo em outros casos.

Aqui está um Java-Sample e o Byte-Code, post e preIncrement não mostram diferença no Bytecode:

 public class PreOrPostIncrement { static int somethingToIncrement = 0; public static void main(String[] args) { final int rounds = 1000; postIncrement(rounds); preIncrement(rounds); } private static void postIncrement(final int rounds) { for (int i = 0; i < rounds; i++) { somethingToIncrement++; } } private static void preIncrement(final int rounds) { for (int i = 0; i < rounds; ++i) { ++somethingToIncrement; } } 

}

E agora para o código de bytes (javap -private -c PreOrPostIncrement):

 public class PreOrPostIncrement extends java.lang.Object{ static int somethingToIncrement; static {}; Code: 0: iconst_0 1: putstatic #10; //Field somethingToIncrement:I 4: return public PreOrPostIncrement(); Code: 0: aload_0 1: invokespecial #15; //Method java/lang/Object."":()V 4: return public static void main(java.lang.String[]); Code: 0: sipush 1000 3: istore_1 4: sipush 1000 7: invokestatic #21; //Method postIncrement:(I)V 10: sipush 1000 13: invokestatic #25; //Method preIncrement:(I)V 16: return private static void postIncrement(int); Code: 0: iconst_0 1: istore_1 2: goto 16 5: getstatic #10; //Field somethingToIncrement:I 8: iconst_1 9: iadd 10: putstatic #10; //Field somethingToIncrement:I 13: iinc 1, 1 16: iload_1 17: iload_0 18: if_icmplt 5 21: return private static void preIncrement(int); Code: 0: iconst_0 1: istore_1 2: goto 16 5: getstatic #10; //Field somethingToIncrement:I 8: iconst_1 9: iadd 10: putstatic #10; //Field somethingToIncrement:I 13: iinc 1, 1 16: iload_1 17: iload_0 18: if_icmplt 5 21: return } 

Não há diferença se você não estiver usando o valor após o incremento no loop.

 for (int i = 0; i < 4; ++i){ cout< 

Ambos os loops imprimirão 0123.

Mas a diferença vem quando você usa o valor após o incremento / decremento no seu loop como abaixo:

Pre Increment Loop:

 for (int i = 0,k=0; i < 4; k=++i){ cout< 

Resultado: 0 0 1 1 2 2 3 3

Pós-incremento Loop:

 for (int i = 0, k=0; i < 4; k=i++){ cout< 

Resultado: 0 0 1 0 2 1 3 2

Espero que a diferença esteja clara comparando a saída. Aponte para observar aqui que o incremento / decremento é sempre executado no final do loop for e, portanto, os resultados podem ser explicados.

Sim existe. A diferença está no valor de retorno. O valor de retorno de “++ i” será o valor após incrementar i. O retorno de “i ++” será o valor antes de incrementar. Isso significa que o código é semelhante ao seguinte:

 int a = 0; int b = ++a; // a is incremented and the result after incrementing is saved to b. int c = a++; // a is incremented again and the result before incremening is saved to c. 

Portanto, a seria 2, ebea cada um deles seria 1.

Eu poderia rewrite o código assim:

 int a = 0; // ++a; a = a + 1; // incrementing first. b = a; // setting second. // a++; c = a; // setting first. a = a + 1; // incrementing second. 

Não há diferença real em ambos os casos ‘ i ‘ será incrementado em 1.

Mas há uma diferença quando você usa em uma expressão, por exemplo:

 int i = 1; int a = ++i; // i is incremented by one and then assigned to a. // Both i and a are now 2. int b = i++; // i is assigned to b and then incremented by one. // b is now 2, and i is now 3 

Há mais em ++ i e i ++ do que loops e diferenças de desempenho. ++ eu retorna um valor-l e i ++ retorna um valor-r. Com base nisso, há muitas coisas que você pode fazer para (++ i), mas não para (i ++).

 1- It is illegal to take the address of post increment result. Compiler won't even allow you. 2- Only constant references to post increment can exist, ie, of the form const T&. 3- You cannot apply another post increment or decrement to the result of i++, ie, there is no such thing as I++++. This would be parsed as ( i ++ ) ++ which is illegal. 4- When overloading pre-/post-increment and decrement operators, programmers are encouraged to define post- increment/decrement operators like: T& operator ++ ( ) { // logical increment return *this; } const T operator ++ ( int ) { T temp( *this ); ++*this; return temp; } 

Em javascript devido ao seguinte i ++ pode ser melhor usar:

 var i=1; alert(i++); // before, 1. current, 1. after, 2. alert(i); // before, 2. current, 2. after, 2. alert(++i); // before, 2. current, 3 after, 3. 

Enquanto arrays (eu acho que todos) e algumas outras funções e chamadas usam 0 como ponto de partida, você teria que definir i como -1 para fazer o loop funcionar com o array ao usar ++ i .

Ao usar o i ++, o valor a seguir usará o valor aumentado. Você poderia dizer que o i ++ é o modo como os humanos contam, porque você pode começar com um 0 .

Isso me surpreende porque as pessoas podem escrever a expressão de incremento em for-loop como i ++.

Em um loop for, quando o terceiro componente é uma instrução de incremento simples, como em

 for (i=0; i 

ou

 for (i=0; i 

não há diferença nas execuções resultantes.

Como o @Jon B diz, não há diferença em um loop for.

Mas em um while ou do...while loop, você pode encontrar algumas diferenças se você está fazendo uma comparação com o ++i ou i++

 while(i++ < 10) { ... } //compare then increment while(++i < 10) { ... } //increment then compare 

Pode haver uma diferença for loops. Esta é a aplicação prática de pós / pré-incremento.

  int i = 0; while(i++ <= 10) { Console.Write(i); } Console.Write(System.Environment.NewLine); i = 0; while(++i <= 10) { Console.Write(i); } Console.ReadLine(); 

Enquanto o primeiro conta 11 e faz loops 11 vezes, o segundo não.

Principalmente isso é usado bastante em um simples momento (x--> 0); - - Loop para iterar por exemplo todos os elementos de um array (isentando foreach-construct here).

Ambos aumentam o número. ++i é equivalente a i = i + 1 .

i++ e ++i são muito parecidos, mas não exatamente iguais. Ambos incrementam o número, mas ++i incrementa o número antes que a expressão atual seja avaliada, enquanto i++ incrementa o número após a expressão ser avaliada.

 int i = 3; int a = i++; // a = 3, i = 4 int b = ++a; // b = 4, a = 

Verifique este link .

Sim, existe uma diferença entre ++i e i++ em um loop for , embora em casos de uso incomuns; quando uma variável de loop com operador de incremento / decremento é usada no bloco for ou dentro da expressão de teste de loop , ou com uma das variables ​​de loop . Não, não é simplesmente uma coisa de syntax.

Como i em um código significa avaliar a expressão i e o operador não significa uma avaliação, mas apenas uma operação;

  • ++i significa valor de incremento de i por 1 e mais tarde avaliar i ,
  • i++ significa avaliar i e posterior valor de incremento de i por 1.

Então, o que é obtido de cada duas expressões difere porque o que é avaliado difere em cada uma delas. Tudo o mesmo para --i e --i

Por exemplo;

 let i = 0 i++ // evaluates to value of i, means evaluates to 0, later increments i by 1, i is now 1 0 i 1 ++i // increments i by 1, i is now 2, later evaluates to value of i, means evaluates to 2 2 i 2 

Em casos de uso incomuns, no entanto o próximo exemplo parece útil ou não, não importa, mostra uma diferença

 for(i=0, j=i; i<10; j=++i){ console.log(j, i) } for(i=0, j=i; i<10; j=i++){ console.log(j, i) } 

Para i de tipos definidos pelo usuário, esses operadores poderiam (mas não deveriam ) ter semânticas significativamente diferentes no contexto de um índice de loop, e isso poderia (mas não deveria) afetar o comportamento do loop descrito.

Além disso, em c++ , geralmente é mais seguro usar o formulário de pré-incremento ( ++i ), porque ele é mais facilmente otimizado. (Scott Langham me espancou com esse boato . Maldito você, Scott)

Eu não sei para as outras línguas, mas em Java + + é um incremento de prefixo que significa: aumentar i por 1 e, em seguida, usar o novo valor de i na expressão em que reside e i ++ é um incremento de postfix que significa o seguinte : use o valor atual de i na expressão e depois aumente em 1. Exemplo:

 public static void main(String [] args){ int a = 3; int b = 5; System.out.println(++a); System.out.println(b++); System.out.println(b); 

} e a saída é:

  • 4
  • 5
  • 6

i ++; ++ i; ambos são semelhantes, pois não são usados ​​em uma expressão.

 class A { public static void main (String []args) { int j = 0 ; int k = 0 ; ++j; k++; System.out.println(k+" "+j); }} prints out : 1 1 
Intereting Posts