Pre-inkrement ++ i inkrementuje wartość i i ocenia do nowej wartości inkrementowanej.
int i = 3;
int preIncrementResult = ++i;
Assert( preIncrementResult == 4 );
Assert( i == 4 );
Post-inkrementacja i ++ inkrementuje wartość i i ocenia do pierwotnej nierekrementowanej wartości.
int i = 3;
int postIncrementResult = i++;
Assert( postIncrementtResult == 3 );
Assert( i == 4 );
W C ++ przyrost jest zwykle preferowany tam, gdzie możesz użyć jednego z nich.
Wynika to z faktu, że jeśli użyjesz funkcji przyrostowej, kompilator może wymagać wygenerowania kodu, który tworzy dodatkową zmienną tymczasową. Wynika to z faktu, że zarówno poprzednia, jak i nowa wartość inkrementowanej zmiennej muszą być gdzieś przechowywane, ponieważ mogą być potrzebne w innym miejscu w ocenianym wyrażeniu.
Tak więc przynajmniej w C ++ może występować różnica w wydajności, która poprowadzi twój wybór, którego użyć.
Jest to głównie problem tylko wtedy, gdy inkrementowana zmienna jest typem zdefiniowanym przez użytkownika z przesłoniętym operatorem ++. W przypadku typów pierwotnych (int itp.) Nie ma różnicy w wydajności. Warto jednak pozostać przy operatorze wstępnego zwiększania jako wskazówkę, chyba że operator po zwiększeniu jest zdecydowanie wymagany.
W C ++, jeśli używasz STL, możesz używać pętli z iteratorami. Te mają głównie przesłonięte operatory ++, więc trzymanie się wstępnego przyrostu jest dobrym pomysłem. Kompilatory cały czas stają się inteligentniejsze, a nowsze mogą być w stanie przeprowadzić optymalizacje, co oznacza, że nie ma różnicy w wydajności - szczególnie jeśli typ inkrementowany jest zdefiniowany w pliku nagłówkowym (jak często są implementacje STL), dzięki czemu kompilator może zobaczyć, jak metoda jest zaimplementowana, a następnie może wiedzieć, jakie optymalizacje są bezpieczne do wykonania. Mimo to prawdopodobnie nadal warto trzymać się wstępnego przyrostu, ponieważ pętle są wykonywane wiele razy, a to oznacza, że niewielka kara za wydajność może wkrótce zostać zwiększona.
W innych językach, takich jak C #, w których operator ++ nie może być przeciążony, nie ma różnicy w wydajności. Używane w pętli do przesuwania zmiennej pętli, operatory przyrostowe przed i po są równoważne.
Poprawka: przeciążenie ++ w języku C # jest dozwolone. Wydaje się jednak, że w porównaniu do C ++ w języku c # nie można przeciążać wersji wstępnej i końcowej niezależnie. Zakładam więc, że jeśli wynik wywołania ++ w C # nie zostanie przypisany do zmiennej lub użyty jako część złożonego wyrażenia, to kompilator zredukuje wersje przed i po ++ do kodu, który działa równorzędnie.
Czy nie byłoby wspaniale, gdyby nazwa C ++ została nazwana ++ C, co oznacza, że można za jej pomocą napisać dobrze zoptymalizowany kod?
Naveen
9
Czy współczesne kompilatory nie powinny być w stanie zoptymalizować tego, skoro wynikowa wartość i tak oczywiście zostanie zniszczona?
che
6
@che - robią to, gdy jest to prosty typ, jednak klasy, które przeciążają operator ++ (takie jak iteratory) to inna historia.
Ferruccio
7
@che: To dobre pytanie. Powód, dla którego kompilatory C ++ nie zastępują „CustomType ++;” z „++ CustomType;” to dlatego, że nie ma gwarancji, że obie funkcje zdefiniowane przez użytkownika mają taki sam efekt. POWINNY ... ale nie ma gwarancji.
Drew Dormann
2
@ michael.bartnett: Dobrze, przeciążenie ++ w C # wydaje się być dostępne. Wydaje się jednak, że w porównaniu do c ++, w języku c # nie można przeciążać wersji wstępnej i końcowej niezależnie. Zakładam więc, że jeśli wynik wywołania ++ w C # nie zostanie przypisany do zmiennej lub użyty jako część złożonego wyrażenia, to kompilator zredukuje wersje przed i po ++ do kodu, który działa równorzędnie.
Scott Langham,
83
W języku C # nie ma różnicy, gdy jest używany w pętli for .
for (int i = 0; i < 10; i++) { Console.WriteLine(i); }
wypisuje to samo co
for (int i = 0; i < 10; ++i) { Console.WriteLine(i); }
Jak zauważyli inni, kiedy używa się ogólnie i ++ i ++, mam subtelną, ale znaczącą różnicę:
int i = 0;
Console.WriteLine(i++); // Prints 0
int j = 0;
Console.WriteLine(++j); // Prints 1
i ++ odczytuje wartość i, a następnie ją zwiększa.
++ i zwiększa wartość i, a następnie ją odczytuje.
Podsumowując: ta sama semantyka po / przed przyrostem jak w C ++.
xtofl
@xtofl - nie jesteś pewien, o co ci chodzi? Właśnie przypadkiem wybrałem c # dla mojego przykładu.
Jon B
3
Nie sądzę, aby pierwszy punkt był istotny. W pętli for (c # lub nie) część przyrostowa jest zawsze wykonywana po treści pętli. Po uruchomieniu zmienna jest modyfikowana niezależnie od tego, czy użyto przyrostu wstępnego, czy wstępnego.
MatthieuP
9
@ MatthieuP - czytam pytanie jako „czy ma znaczenie, czy używasz i ++ czy ++ i w pętli for”. Odpowiedź brzmi „nie, nie”.
Jon B
1
@JonB Kolejność operacji w odpowiedzi nie jest dokładnie poprawna. Zarówno ++ii i++wykonaj te same operacje w tej samej kolejności: utwórz tymczasową kopię i; zwiększyć wartość temp, aby uzyskać nową wartość (nie zastępować temp); zapisz nową wartość w i; teraz, jeśli ++iwynik jest zwracany, to nowa wartość; jeśli i++wynik jest zwracany, to kopia tymczasowa. Bardziej szczegółowa odpowiedź tutaj: stackoverflow.com/a/3346729/3330348
PiotrWolkowski
51
Pytanie brzmi:
Czy istnieje różnica w ++ i i ++ w pętli for?
Odpowiedź brzmi: nie .
Dlaczego każda inna odpowiedź musi zawierać szczegółowe objaśnienia dotyczące inkrementacji przed i po, gdy nie jest to nawet zadawane?
Ta pętla for:
for (int i = 0; // Initialization
i < 5; // Condition
i++) // Increment
{
Output(i);
}
Przetłumaczyłbym na ten kod bez użycia pętli:
int i = 0; // Initialization
loopStart:
if (i < 5) // Condition
{
Output(i);
i++ or ++i; // Increment
goto loopStart;
}
Czy ma to teraz znaczenie, czy umieścisz tutaj, i++czy ++ijako przyrost? Nie, nie dlatego, że wartość zwracana operacji przyrostowej jest nieznaczna. ibędzie zwiększany PO wykonaniu kodu znajdującego się w treści pętli for.
Ponieważ pytasz o różnicę w pętli, myślę, że masz na myśli
for(int i=0; i<10; i++)
...;
W takim przypadku nie ma różnicy w większości języków: Pętla zachowuje się tak samo, niezależnie od tego, czy piszesz i++i ++i. W C ++ możesz pisać własne wersje operatorów ++ i możesz zdefiniować dla nich osobne znaczenia, jeśli ijest to typ zdefiniowany przez użytkownika (na przykład twoja własna klasa).
Powodem, dla którego nie ma to znaczenia powyżej, jest to, że nie używasz wartości i++. Inną rzeczą jest, kiedy to robisz
for(int i=0, a = 0; i<10; a = i++)
...;
Teraz jest różnica, ponieważ, jak podkreślają inni, i++oznacza przyrost, ale oszacowanie do poprzedniej wartości , ale ++ioznacza przyrost, ale oszacowanie doi (w ten sposób oszacowałoby do nowej wartości). W powyższym przypadku aprzypisana jest poprzednia wartość i, natomiast i jest zwiększane.
W C ++ nie zawsze jest możliwe, aby kompilator uniknął tworzenia wartości tymczasowych, dlatego preferowana jest forma wstępnego przyrostu.
David Thornley
jak piszę, jeśli masz i typu zdefiniowanego przez użytkownika, mogą mieć inną semantykę. ale jeśli użyjesz i typu pierwotnego, nie robi to różnicy dla pierwszej pętli. ponieważ jest to pytanie agnostyczne związane z językiem, pomyślałem, że nie będę pisał zbyt wiele o specyficznych dla C ++ rzeczach.
Johannes Schaub - litb
15
Jak pokazuje ten kod (patrz nieszyfrowany MSIL w komentarzach), kompilator C # 3 nie wprowadza rozróżnienia między i ++ i ++ i w pętli for. Gdyby wziąć wartość i ++ lub ++ i, na pewno byłaby różnica (ta została skompilowana w Visutal Studio 2008 / Release Build):
Jeden (++ i) to wzrost wstępny, jeden (i ++) to wzrost wstępny. Różnica polega na tym, jaka wartość jest natychmiast zwracana z wyrażenia.
// Psuedocode
int i = 0;
print i++; // Prints 0
print i; // Prints 1
int j = 0;
print ++j; // Prints 1
print j; // Prints 1
Edycja: Woops, całkowicie zignorowałem pętlę rzeczy. Nie ma żadnej rzeczywistej różnicy w przypadku pętli, gdy jest to część „krokowa” (dla (...; ...;)), ale może wejść w grę w innych przypadkach.
Nie ma różnicy, jeśli nie używasz wartości po inkrementacji w pętli.
for (int i = 0; i < 4; ++i){
cout<<i;
}
for (int i = 0; i < 4; i++){
cout<<i;
}
Obie pętle wydrukują 0123.
Ale różnica pojawia się, gdy używasz wartości po inkrementacji / dekrementacji w swojej pętli, jak poniżej:
Pętla przed przyrostem:
for (int i = 0,k=0; i < 4; k=++i){
cout<<i<<" ";
cout<<k<<" ";
}
Wyjście: 0 0 1 1 2 2 3 3
Pętla przyrostowa:
for (int i = 0, k=0; i < 4; k=i++){
cout<<i<<" ";
cout<<k<<" ";
}
Wyjście: 0 0 1 0 2 1 3 2
Mam nadzieję, że różnica jest wyraźna poprzez porównanie wyników. Należy zwrócić uwagę na to, że inkrementacja / dekrementacja jest zawsze wykonywana na końcu pętli for, a zatem wyniki można wyjaśnić.
Oto przykład Java, a kod bajtowy, post- i preIncrement nie pokazują żadnej różnicy w kodzie bajtowym:
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;
}
}
}
A teraz dla kodu bajtowego (javap -private -c PreOrPostIncrement):
Tak jest. Różnica polega na wartości zwracanej. Zwracana wartość „++ i” będzie wartością po inkrementacji i. Zwrot „i ++” będzie wartością przed inkrementacją. Oznacza to, że kod wygląda następująco:
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.
Dlatego a będzie równe 2, a b i c będą równe 1.
Mógłbym przepisać kod w ten sposób:
int a = 0;
// ++a;
a = a + 1; // incrementing first.
b = a; // setting second.
// a++;
c = a; // setting first.
a = a + 1; // incrementing second.
W obu przypadkach nie ma faktycznej różnicy ' i' zostanie zwiększona o 1.
Ale jest różnica, gdy używasz go w wyrażeniu, na przykład:
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
++ i i ++ to coś więcej niż pętle i różnice w wydajności. ++ i zwraca wartość l, a i ++ zwraca wartość r. Na tej podstawie istnieje wiele rzeczy, które możesz zrobić (++ i), ale nie (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, i.e., of the form const T&.
3- You cannot apply another post increment or decrement to the result of i++, i.e., 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;
}
Podczas gdy tablice (myślę, że wszystkie) oraz niektóre inne funkcje i wywołania używają 0 jako punktu początkowego, musiałbyś ustawić i na -1, aby pętla działała z tablicą podczas używania ++ i .
Podczas korzystania z i ++ następująca wartość wykorzysta zwiększoną wartość. Można powiedzieć, że i ++ to sposób, w jaki liczą się ludzie, ponieważ możesz zacząć od 0 .
Powyższy obraz pokazuje, że FOR można przekonwertować na WHILE , ponieważ ostatecznie mają one całkowicie ten sam kod asemblera (przynajmniej w gcc). Więc możemy rozbić FOR na kilka części, aby zrozumieć, co robi.
for(i =0; i <5;++i){DoSomethingA();DoSomethingB();}
jest równa wersji WHILE
i =0;//first argument (a statement) of forwhile(i <5/*second argument (a condition) of for*/){DoSomethingA();DoSomethingB();++i;//third argument (another statement) of for}
Oznacza to, że możesz użyć FOR jako prostej wersji WHILE :
Pierwszy argument FOR (int i) jest wykonywany na zewnątrz przed pętlą.
Trzeci argument FOR (i ++ lub ++ i) jest wykonywany wewnątrz w ostatnim wierszu pętli.
TL: DR: bez względu na to, czy i++lub ++i, wiemy, że gdy są samodzielne, nie mają znaczenia, ale dają +1 dla siebie.
W szkole zwykle uczą języka i ++, ale jest też wiele osób, które preferują język i ++ z kilku powodów .
UWAGA: W przeszłości i ++ miał bardzo mały wpływ na wydajność, ponieważ nie tylko sam plus jeden, ale także zachowuje oryginalną wartość w rejestrze. Ale na razie nie ma znaczenia, ponieważ kompilator sprawia, że część dodatnia jest taka sama.
Różnice mogą występować w przypadku pętli. Jest to praktyczne zastosowanie post / przyrostu.
int i = 0;
while(i++ <= 10) {
Console.Write(i);
}
Console.Write(System.Environment.NewLine);
i = 0;
while(++i <= 10) {
Console.Write(i);
}
Console.ReadLine();
Podczas gdy pierwszy liczy się do 11 i zapętla 11 razy, drugi nie.
Najczęściej jest to używane raczej w krótkim czasie (x--> 0); - - Pętla iteruje na przykład wszystkie elementy tablicy (wyłączając tutaj konstrukcje foreach).
Obaj zwiększają liczbę. ++ijest równoważne z i = i + 1.
i++i ++isą bardzo podobne, ale nie dokładnie takie same. Oba zwiększają liczbę, ale ++izwiększają liczbę przed obliczeniem bieżącego wyrażenia, podczas gdy i++zwiększają liczbę po obliczeniu wyrażenia.
int i = 3;
int a = i++; // a = 3, i = 4
int b = ++a; // b = 4, a =
Tak, istnieje różnica pomiędzy ++ii i++w forpętli, choć w nietypowych przypadkach użycia; gdy zmienna pętli z operatorem zwiększania / zmniejszania jest używana w bloku for lub w wyrażeniu testu pętli lub z jedną ze zmiennych pętli . Nie, nie jest to po prostu składnia.
Jak iw kodzie oznacza wyrażenie, ia operator nie oznacza oceny, a jedynie operację;
++ioznacza wartość przyrostu o i1 i późniejszą ocenę i,
i++oznacza oszacowanie, ia następnie zwiększenie wartości o i1.
To, co jest otrzymywane z każdego z dwóch wyrażeń, różni się, ponieważ to, co jest oceniane, różni się w każdym z nich. Wszystko to samo dla --iii--
Na przykład;
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
W nietypowych przypadkach, jednak następny przykład wydaje się przydatny lub nie ma znaczenia, pokazuje różnicę
odpowiada bardziej bezpośrednio na pytania, niż te, które przeczytałem.
Selçuk
-2
W przypadku itypów zdefiniowanych przez użytkownika operatory te mogą (ale nie powinny ) mieć znacząco różne dane sematyczne w kontekście indeksu pętli, a to może (ale nie powinno) wpływać na zachowanie opisanej pętli.
Ponadto w c++zasadzie najbezpieczniej jest używać formularza wstępnego przyrostu ( ++i), ponieważ łatwiej go zoptymalizować. (Scott Langham pobił mnie na ten smakołyk . Przeklinam cię, Scott)
Semantyka postfiksa powinna być większa niż prefiks. -1
xtofl
-2
Dont wiem dla innych języków, ale w Javie ++ i jest prefiks przyrost który oznacza: zwiększenie I o 1, a następnie użyć nowej wartości I w wypowiedzi, w których I miejsce zamieszkania, a ja ++ jest przyrost postfix co oznacza, że następuje : użyj bieżącej wartości i w wyrażeniu, a następnie zwiększ ją o 1. Przykład:
public static void main(String [] args){
int a = 3;
int b = 5;
System.out.println(++a);
System.out.println(b++);
System.out.println(b);
Odpowiedzi:
++ jest znany jako postfix.
dodać 1 do a, zwraca starą wartość.
++ a jest znany jako przedrostek.
dodać 1 do a, zwraca nową wartość.
DO#:
Wynik:
foreach
awhile
pętle zależą od używanego typu przyrostu. Z pętlami jak poniżej nie ma znaczenia, ponieważ nie używasz wartości zwracanej przez i:Jeśli zastosowana zostanie wartość oszacowana, wówczas rodzaj przyrostu będzie znaczący:
źródło
Pre-inkrement ++ i inkrementuje wartość i i ocenia do nowej wartości inkrementowanej.
Post-inkrementacja i ++ inkrementuje wartość i i ocenia do pierwotnej nierekrementowanej wartości.
W C ++ przyrost jest zwykle preferowany tam, gdzie możesz użyć jednego z nich.
Wynika to z faktu, że jeśli użyjesz funkcji przyrostowej, kompilator może wymagać wygenerowania kodu, który tworzy dodatkową zmienną tymczasową. Wynika to z faktu, że zarówno poprzednia, jak i nowa wartość inkrementowanej zmiennej muszą być gdzieś przechowywane, ponieważ mogą być potrzebne w innym miejscu w ocenianym wyrażeniu.
Tak więc przynajmniej w C ++ może występować różnica w wydajności, która poprowadzi twój wybór, którego użyć.
Jest to głównie problem tylko wtedy, gdy inkrementowana zmienna jest typem zdefiniowanym przez użytkownika z przesłoniętym operatorem ++. W przypadku typów pierwotnych (int itp.) Nie ma różnicy w wydajności. Warto jednak pozostać przy operatorze wstępnego zwiększania jako wskazówkę, chyba że operator po zwiększeniu jest zdecydowanie wymagany.
Tutaj jest trochę więcej dyskusji:
https://web.archive.org/web/20170405054235/http://en.allexperts.com/q/C-1040/Increment-operators.htm
W C ++, jeśli używasz STL, możesz używać pętli z iteratorami. Te mają głównie przesłonięte operatory ++, więc trzymanie się wstępnego przyrostu jest dobrym pomysłem. Kompilatory cały czas stają się inteligentniejsze, a nowsze mogą być w stanie przeprowadzić optymalizacje, co oznacza, że nie ma różnicy w wydajności - szczególnie jeśli typ inkrementowany jest zdefiniowany w pliku nagłówkowym (jak często są implementacje STL), dzięki czemu kompilator może zobaczyć, jak metoda jest zaimplementowana, a następnie może wiedzieć, jakie optymalizacje są bezpieczne do wykonania. Mimo to prawdopodobnie nadal warto trzymać się wstępnego przyrostu, ponieważ pętle są wykonywane wiele razy, a to oznacza, że niewielka kara za wydajność może wkrótce zostać zwiększona.
W innych językach, takich jak C #, w których operator ++ nie może być przeciążony, nie ma różnicy w wydajności. Używane w pętli do przesuwania zmiennej pętli, operatory przyrostowe przed i po są równoważne.
Poprawka: przeciążenie ++ w języku C # jest dozwolone. Wydaje się jednak, że w porównaniu do C ++ w języku c # nie można przeciążać wersji wstępnej i końcowej niezależnie. Zakładam więc, że jeśli wynik wywołania ++ w C # nie zostanie przypisany do zmiennej lub użyty jako część złożonego wyrażenia, to kompilator zredukuje wersje przed i po ++ do kodu, który działa równorzędnie.
źródło
W języku C # nie ma różnicy, gdy jest używany w pętli for .
wypisuje to samo co
Jak zauważyli inni, kiedy używa się ogólnie i ++ i ++, mam subtelną, ale znaczącą różnicę:
i ++ odczytuje wartość i, a następnie ją zwiększa.
++ i zwiększa wartość i, a następnie ją odczytuje.
źródło
++i
ii++
wykonaj te same operacje w tej samej kolejności: utwórz tymczasową kopięi
; zwiększyć wartość temp, aby uzyskać nową wartość (nie zastępować temp); zapisz nową wartość wi
; teraz, jeśli++i
wynik jest zwracany, to nowa wartość; jeślii++
wynik jest zwracany, to kopia tymczasowa. Bardziej szczegółowa odpowiedź tutaj: stackoverflow.com/a/3346729/3330348Pytanie brzmi:
Odpowiedź brzmi: nie .
Dlaczego każda inna odpowiedź musi zawierać szczegółowe objaśnienia dotyczące inkrementacji przed i po, gdy nie jest to nawet zadawane?
Ta pętla for:
Przetłumaczyłbym na ten kod bez użycia pętli:
Czy ma to teraz znaczenie, czy umieścisz tutaj,
i++
czy++i
jako przyrost? Nie, nie dlatego, że wartość zwracana operacji przyrostowej jest nieznaczna.i
będzie zwiększany PO wykonaniu kodu znajdującego się w treści pętli for.źródło
Ponieważ pytasz o różnicę w pętli, myślę, że masz na myśli
W takim przypadku nie ma różnicy w większości języków: Pętla zachowuje się tak samo, niezależnie od tego, czy piszesz
i++
i++i
. W C ++ możesz pisać własne wersje operatorów ++ i możesz zdefiniować dla nich osobne znaczenia, jeślii
jest to typ zdefiniowany przez użytkownika (na przykład twoja własna klasa).Powodem, dla którego nie ma to znaczenia powyżej, jest to, że nie używasz wartości
i++
. Inną rzeczą jest, kiedy to robiszTeraz jest różnica, ponieważ, jak podkreślają inni,
i++
oznacza przyrost, ale oszacowanie do poprzedniej wartości , ale++i
oznacza przyrost, ale oszacowanie doi
(w ten sposób oszacowałoby do nowej wartości). W powyższym przypadkua
przypisana jest poprzednia wartość i, natomiast i jest zwiększane.źródło
Jak pokazuje ten kod (patrz nieszyfrowany MSIL w komentarzach), kompilator C # 3 nie wprowadza rozróżnienia między i ++ i ++ i w pętli for. Gdyby wziąć wartość i ++ lub ++ i, na pewno byłaby różnica (ta została skompilowana w Visutal Studio 2008 / Release Build):
źródło
Jeden (++ i) to wzrost wstępny, jeden (i ++) to wzrost wstępny. Różnica polega na tym, jaka wartość jest natychmiast zwracana z wyrażenia.
Edycja: Woops, całkowicie zignorowałem pętlę rzeczy. Nie ma żadnej rzeczywistej różnicy w przypadku pętli, gdy jest to część „krokowa” (dla (...; ...;)), ale może wejść w grę w innych przypadkach.
źródło
Nie ma różnicy, jeśli nie używasz wartości po inkrementacji w pętli.
Obie pętle wydrukują 0123.
Ale różnica pojawia się, gdy używasz wartości po inkrementacji / dekrementacji w swojej pętli, jak poniżej:
Pętla przed przyrostem:
Wyjście: 0 0 1 1 2 2 3 3
Pętla przyrostowa:
Wyjście: 0 0 1 0 2 1 3 2
Mam nadzieję, że różnica jest wyraźna poprzez porównanie wyników. Należy zwrócić uwagę na to, że inkrementacja / dekrementacja jest zawsze wykonywana na końcu pętli for, a zatem wyniki można wyjaśnić.
źródło
Oto przykład Java, a kod bajtowy, post- i preIncrement nie pokazują żadnej różnicy w kodzie bajtowym:
A teraz dla kodu bajtowego (javap -private -c PreOrPostIncrement):
źródło
Tak jest. Różnica polega na wartości zwracanej. Zwracana wartość „++ i” będzie wartością po inkrementacji i. Zwrot „i ++” będzie wartością przed inkrementacją. Oznacza to, że kod wygląda następująco:
Dlatego a będzie równe 2, a b i c będą równe 1.
Mógłbym przepisać kod w ten sposób:
źródło
W obu przypadkach nie ma faktycznej różnicy '
i
' zostanie zwiększona o 1.Ale jest różnica, gdy używasz go w wyrażeniu, na przykład:
źródło
++ i i ++ to coś więcej niż pętle i różnice w wydajności. ++ i zwraca wartość l, a i ++ zwraca wartość r. Na tej podstawie istnieje wiele rzeczy, które możesz zrobić (++ i), ale nie (i ++).
źródło
Zastanawia mnie, dlaczego ludzie mogą pisać wyrażenie przyrostowe w pętli for jako i ++.
W pętli for, gdy trzeci składnik jest prostą instrukcją przyrostową, jak w
lub
nie ma różnicy w wynikowych wykonaniach.
źródło
Jak mówi @Jon B , nie ma różnicy w pętli for.
Ale w pętli
while
lubdo...while
możesz znaleźć pewne różnice, jeśli porównujesz z++i
lubi++
źródło
W javascript z powodu następującego i ++ może być lepiej użyć:
Podczas gdy tablice (myślę, że wszystkie) oraz niektóre inne funkcje i wywołania używają 0 jako punktu początkowego, musiałbyś ustawić i na -1, aby pętla działała z tablicą podczas używania ++ i .
Podczas korzystania z i ++ następująca wartość wykorzysta zwiększoną wartość. Można powiedzieć, że i ++ to sposób, w jaki liczą się ludzie, ponieważ możesz zacząć od 0 .
źródło
jest równa wersji WHILE
źródło
Różnice mogą występować w przypadku pętli. Jest to praktyczne zastosowanie post / przyrostu.
Podczas gdy pierwszy liczy się do 11 i zapętla 11 razy, drugi nie.
Najczęściej jest to używane raczej w krótkim czasie (x--> 0); - - Pętla iteruje na przykład wszystkie elementy tablicy (wyłączając tutaj konstrukcje foreach).
źródło
Obaj zwiększają liczbę.
++i
jest równoważne zi = i + 1
.i++
i++i
są bardzo podobne, ale nie dokładnie takie same. Oba zwiększają liczbę, ale++i
zwiększają liczbę przed obliczeniem bieżącego wyrażenia, podczas gdyi++
zwiększają liczbę po obliczeniu wyrażenia.Sprawdź ten link .
źródło
Tak, istnieje różnica pomiędzy
++i
ii++
wfor
pętli, choć w nietypowych przypadkach użycia; gdy zmienna pętli z operatorem zwiększania / zmniejszania jest używana w bloku for lub w wyrażeniu testu pętli lub z jedną ze zmiennych pętli . Nie, nie jest to po prostu składnia.Jak
i
w kodzie oznacza wyrażenie,i
a operator nie oznacza oceny, a jedynie operację;++i
oznacza wartość przyrostu oi
1 i późniejszą ocenęi
,i++
oznacza oszacowanie,i
a następnie zwiększenie wartości oi
1.To, co jest otrzymywane z każdego z dwóch wyrażeń, różni się, ponieważ to, co jest oceniane, różni się w każdym z nich. Wszystko to samo dla
--i
ii--
Na przykład;
W nietypowych przypadkach, jednak następny przykład wydaje się przydatny lub nie ma znaczenia, pokazuje różnicę
źródło
W przypadku
i
typów zdefiniowanych przez użytkownika operatory te mogą (ale nie powinny ) mieć znacząco różne dane sematyczne w kontekście indeksu pętli, a to może (ale nie powinno) wpływać na zachowanie opisanej pętli.Ponadto w
c++
zasadzie najbezpieczniej jest używać formularza wstępnego przyrostu (++i
), ponieważ łatwiej go zoptymalizować. (Scott Langham pobił mnie na ten smakołyk . Przeklinam cię, Scott)źródło
Dont wiem dla innych języków, ale w Javie ++ i jest prefiks przyrost który oznacza: zwiększenie I o 1, a następnie użyć nowej wartości I w wypowiedzi, w których I miejsce zamieszkania, a ja ++ jest przyrost postfix co oznacza, że następuje : użyj bieżącej wartości i w wyrażeniu, a następnie zwiększ ją o 1. Przykład:
}, a wynik to:
źródło
i ++; ++ i; oba są podobne, ponieważ nie są używane w wyrażeniu.
źródło