C: jaka jest różnica między ++i A i++?

W C, jaka jest różnica między użyciem ++i i i++, A które powinno być używane w bloku inkrementacji pętli for?

Author: Mark Harrison, 2008-08-24

21 answers

  • ++i zwiększy wartość i, a następnie zwróci wartość zwiększoną.

     i = 1;
     j = ++i;
     (i is 2, j is 2)
    
  • i++ zwiększy wartość i, ale zwróci oryginalną wartość i przed zwiększeniem.

     i = 1;
     j = i++;
     (i is 2, j is 1)
    

Dla pętli for, albo działa. ++i wydaje się bardziej powszechne, być może dlatego, że jest to, co jest używane w K & R.

W każdym razie postępuj zgodnie z wytycznymi " preferuj ++i nad i++" i nie pójdziesz źle.

Jest kilka uwag dotyczących efektywności ++i i i++. W każdym kompilatorze nie będącym studentem nie będzie różnicy w wydajności. Możesz to sprawdzić, patrząc na wygenerowany kod, który będzie identyczny.

Pytanie o efektywność jest interesujące... oto moja próba odpowiedzi: czy jest różnica w wydajności między i++ I ++i w C?

As @OnFreund notes, it ' s different for a C++ object, since operator++() jest funkcją i kompilator nie może wiedzieć, aby zoptymalizować tworzenie tymczasowego obiektu do przechowywania wartości pośredniej.

 1192
Author: Mark Harrison,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-02-28 10:40:26

I++ jest znany jako Post Increment podczas gdy ++i jest nazywany Pre Increment.

i++

i++ jest post incrementem, ponieważ zwiększa wartość i o 1 po zakończeniu operacji.

Zobaczmy następujący przykład:

int i = 1, j;
j = i++;

Tutaj wartość j = 1 ale i = 2. Tutaj wartość i zostanie przypisana do j najpierw i zostanie zwiększona.

++i

++i na pre increment, ponieważ zwiększa wartość i o 1 przed wykonaniem operacji. Oznacza to, że j = i; wykona po i++.

Zobaczmy następujący przykład:

int i = 1, j;
j = ++i;

Tutaj wartość j = 2 ale i = 2. Tutaj wartość i zostanie przypisana do j po przyrostku i z i. Podobnie {[13] } zostanie wykonane przed j=i;.

Dla Twojego pytania który powinien być użyty w bloku inkrementacji pętli for? odpowiedź brzmi: możesz użyć dowolnego.. nieważne. Spowoduje to wykonanie pętli for tego samego nie. razy.

for(i=0; i<5; i++)
   printf("%d ",i);

I

for(i=0; i<5; ++i)
   printf("%d ",i);

Obie pętle będą produkować to samo wyjście. ie 0 1 2 3 4.

Liczy się tylko to, gdzie go używasz.
for(i = 0; i<5;)
    printf("%d ",++i);

W tym przypadku wyjście będzie 1 2 3 4 5.

 199
Author: Parag,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-27 13:55:54

Proszę nie martwić się o "wydajność" (szybkość, naprawdę), z których jeden jest szybszy. W dzisiejszych czasach mamy Kompilatory, które zajmują się tymi rzeczami. Używaj tego, który ma sens, na podstawie którego wyraźniej pokazuje twoje intencje.

 46
Author: Andy Lester,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-26 21:57:50

++i zwiększa wartość, a następnie zwraca ją.

i++ Zwraca wartość, a następnie ją zwiększa.

To subtelna różnica.

Dla pętli for, użyj ++i, ponieważ jest nieco szybsza. i++ stworzy dodatkową kopię, która zostanie wyrzucona.

 41
Author: Ryan Fox,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-26 10:40:58

i++: w tym scenariuszu najpierw zostanie przypisana wartość, a następnie nastąpi inkrementacja.

++i: w tym scenariuszu najpierw następuje przyrost, a następnie przypisana jest wartość

Poniżej znajduje się wizualizacja obrazu, a także Oto ładny praktyczny film , który demonstruje to samo.

Tutaj wpisz opis obrazka

 36
Author: Shivprasad Koirala,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-06-08 07:11:22

Powód ++i Może być nieco szybsze niż i++ jest to, że i++ może wymagać lokalnej kopii wartości i, zanim zostanie ona zwiększona, podczas gdy ++i nigdy tego nie robi. W niektórych przypadkach niektóre Kompilatory zoptymalizują go, jeśli to możliwe... ale nie zawsze jest to możliwe i nie wszystkie Kompilatory to robią.

Staram się nie polegać zbytnio na optymalizacjach kompilatorów, więc podążam za radą Ryana Foxa: Kiedy Mogę używać obu, używam ++i.

 22
Author: OysterD,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-26 10:41:58

Obie zwiększają liczbę. {[1] } jest równoważne i = i + 1.

i++ i ++i są bardzo podobne, ale nie do końca takie same. Zarówno zwiększa liczbę, ale ++i zwiększa liczbę przed obliczeniem bieżącego wyrażenia, podczas gdy i++ zwiększa liczbę po obliczeniu wyrażenia.

Przykład:

int i = 1;
int x = i++; //x is 1, i is 2
int y = ++i; //y is 3, i is 3
 15
Author: Usman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-06-08 07:05:32

Efektywny wynik użycia obu w pętli jest identyczny. Innymi słowy, pętla zrobi dokładnie to samo w obu przypadkach.

Jeśli chodzi o wydajność, może być kara związana z wyborem i++ nad ++i. jeśli chodzi o specyfikację języka, użycie operatora post-increment powinno utworzyć dodatkową kopię wartości, na której działa operator. To może być źródłem dodatkowych operacji.

Należy jednak wziąć pod uwagę dwa główne problemy z poprzedzająca logika.

  1. Nowoczesne Kompilatory są świetne. Wszystkie dobre Kompilatory są na tyle inteligentne, że zdają sobie sprawę, że widzą przyrost liczby całkowitej w pętli for i zoptymalizują obie metody do tego samego wydajnego kodu. Jeśli użycie post-increment nad pre - increment powoduje, że twój program działa wolniej, To używasz kompilatora terrible.

  2. Jeśli chodzi o złożoność czasu pracy, obie metody (nawet jeśli kopia jest faktycznie wykonywane) są równoważne. Liczba instrukcji wykonywanych wewnątrz pętli powinna znacząco zdominować liczbę operacji w operacji inkrementacji. W związku z tym, w każdej pętli o znaczącej wielkości, kara metody inkrementacji zostanie znacznie przyćmiona przez wykonanie ciała pętli. Innymi słowy, o wiele lepiej jest martwić się o optymalizację kodu w pętli, a nie przyrost.

Moim zdaniem cała sprawa po prostu sprowadza się do preferencji stylu. Jeśli uważasz, że pre-increment jest bardziej czytelny, użyj go. Osobiście wolę post-incrment, ale to prawdopodobnie dlatego, że to było to, czego uczono mnie, zanim wiedziałem coś o optymalizacji.

Jest to kwintesencyjny przykład przedwczesnej optymalizacji, a takie kwestie mogą odwrócić naszą uwagę od poważnych problemów w projektowaniu. Jest to jednak nadal dobre pytanie, ponieważ nie ma jednolitości w użyciu lub konsensusu w "najlepszym praktyka."

 15
Author: dusktreader,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-03-21 17:33:36

++i (operacja przedrostka): przyrosty, a następnie przypisuje wartość
(eg): int i = 5, int b = ++i W tym przypadku 6 jest najpierw przypisane do b, a następnie przyrosty do 7 i tak dalej.

i++ (Operacja Postfix): przypisuje a następnie zwiększa wartość
(eg): int i = 5, int b = i++ W tym przypadku 5 jest najpierw przypisane do b, a następnie przyrosty do 6 i tak dalej.

Incase of for loop: i++ jest najczęściej używany, ponieważ zwykle używamy wartości początkowej i przed inkrementacja w pętli. Ale w zależności od logiki programu może się różnić.

 10
Author: Anands23,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-06-08 07:08:53

Jedyną różnicą jest kolejność operacji pomiędzy przyrostem zmiennej a wartością zwracaną przez operator.

Ten kod i jego wyjście wyjaśnia różnicę:

#include<stdio.h>

int main(int argc, char* argv[])
{
  unsigned int i=0, a;
  printf("i initial value: %d; ", i);
  a = i++;
  printf("value returned by i++: %d, i after: %d\n", a, i);
  i=0;
  printf("i initial value: %d; ", i);
  a = ++i;
  printf(" value returned by ++i: %d, i after: %d\n",a, i);
}

Wyjście to:

i initial value: 0; value returned by i++: 0, i after: 1
i initial value: 0;  value returned by ++i: 1, i after: 1

Więc zasadniczo ++i Zwraca wartość po jej zwiększeniu, podczas gdy i++ Zwraca wartość przed jej zwiększeniem. Na końcu, w obu przypadkach wartość i zostanie zwiększona.

Inny przykład:

#include<stdio.h>

int main ()
  int i=0;
  int a = i++*2;
  printf("i=0, i++*2=%d\n", a);
  i=0;
  a = ++i * 2;
  printf("i=0, ++i*2=%d\n", a);
  i=0;
  a = (++i) * 2;
  printf("i=0, (++i)*2=%d\n", a);
  i=0;
  a = (++i) * 2;
  printf("i=0, (++i)*2=%d\n", a);
  return 0;
}

Wyjście:

i=0, i++*2=0
i=0, ++i*2=2
i=0, (++i)*2=2
i=0, (++i)*2=2

Wiele razy nie ma różnicy

Różnice są wyraźne, gdy zwracana wartość jest przypisana do innej zmiennej lub gdy przyrost jest wykonywany w połączeniu z innymi operacjami, w których stosuje się pierwszeństwo operacji (i++*2 różni się od ++i*2, ale (i++)*2 i (++i)*2 zwraca tę samą wartość) w wielu przypadkach są one wymienne. Klasyczny przykład to składnia pętli for:

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

MA ten sam efekt z

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

Rule to remember

Aby nie wprowadzać w błąd między dwoma operatorami, przyjęłam tę zasadę:

Przypisanie pozycji operatora ++ w odniesieniu do zmiennej i do porządku operacji ++ w odniesieniu do przypisania

Powiedział innymi słowy:

  • ++ przed i oznacza, że inkrementacja musi być przeprowadzona przed przypisaniem;
  • ++ po i oznacza, że inkrementacja musi być przeprowadzona po przypisaniu:
 9
Author: Francesco Boi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-10-19 16:01:04

++i: jest przed przyrostem, drugi jest po przyrostie.

i++: pobiera element, a następnie zwiększa go.
++i: inkrementuje i, a następnie zwraca element.

Przykład:

int i = 0;
printf("i: %d\n", i);
printf("i++: %d\n", i++);
printf("++i: %d\n", ++i);

Wyjście:

i: 0
i++: 0
++i: 2
 8
Author: Scitech,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-06-08 07:09:30

I++ I ++i

Ten mały kod może pomóc wizualizować różnicę pod innym kątem niż już zamieszczone odpowiedzi:

int i = 10, j = 10;
  
printf ("i is %i \n", i);
printf ("i++ is %i \n", i++);
printf ("i is %i \n\n", i);
  
printf ("j is %i \n", j);
printf ("++j is %i \n", ++j);
printf ("j is %i \n", j);

Wynik jest:

//Remember that the values are i = 10, and j = 10

i is 10 
i++ is 10     //Assigns (print out), then increments
i is 11 

j is 10 
++j is 11    //Increments, then assigns (print out)
j is 11 

Zwróć uwagę na sytuacje Przed i po.

For loop

Jeśli chodzi o to, który z nich powinien być użyty w bloku inkrementacji pętli for, myślę, że najlepszym sposobem na podjęcie decyzji jest użycie dobrego przykładu:

int i, j;

for (i = 0; i <= 3; i++)
    printf (" > iteration #%i", i);

printf ("\n");

for (j = 0; j <= 3; ++j)
    printf (" > iteration #%i", j);

Wynik jest:

> iteration #0 > iteration #1 > iteration #2 > iteration #3
> iteration #0 > iteration #1 > iteration #2 > iteration #3 

I don ' t wiem o tobie, ale nie widzę różnicy w jego użyciu, przynajmniej w pętli for.

 7
Author: carloswm85,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-20 09:12:55

Poniższy fragment kodu C ilustruje różnicę między operatorami pre i post increment i decrement:

int  i;
int  j;

Operatory przyrostowe:

i = 1;
j = ++i;    // i is now 2, j is also 2
j = i++;    // i is now 3, j is 2
 6
Author: Nihal Reddy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-06-08 07:06:09

Zakładam, że teraz rozumiesz różnicę w semantyce (choć szczerze mówiąc zastanawiam się, dlaczego ludzie pytają "co oznacza operator x" o przepełnienie stosu, zamiast czytać, wiesz, książka albo samouczek internetowy czy coś.

Ale w każdym razie, jeśli chodzi o to, którego z nich użyć, ignoruj pytania dotyczące wydajności, które są mało ważne nawet w C++. To jest zasada, którą powinieneś stosować przy podejmowaniu decyzji którego użyć:

Powiedz, co masz na myśli w kodzie.

Jeśli nie potrzebujesz value-before-increment in your statement, don ' t use that form of the operator. To drobny problem, ale chyba, że pracujesz z przewodnikiem stylu, który zakazuje jednego wersja na korzyść innych (aka poradnik w stylu Kościana głowa), należy użyć forma, która najbardziej dokładnie wyraża to, co próbujesz zrobić.

QED, użyj wersji pre-increment:

for (int i = 0; i != X; ++i) ...
 5
Author: Scott Urban,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-04 17:20:53

Różnicę można zrozumieć za pomocą poniższego prostego kodu C++:

int i, j, k, l;
i = 1; //initialize int i with 1
j = i+1; //add 1 with i and set that as the value of j. i is still 1
k = i++; //k gets the current value of i, after that i is incremented. So here i is 2, but k is 1
l = ++i; // i is incremented first and then returned. So the value of i is 3 and so does l.
cout << i << ' ' << j << ' ' << k << ' '<< l << endl;
return 0;
 5
Author: IOstream,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-12 21:13:13

Główna różnica to

  • i++ Post ( Po przyroście ) i
  • ++i Pre (Before Increment)

    • post if i =1 pętla zwiększa się jak 1,2,3,4,n
    • pre if i =1 pętla zwiększa się jak 2,3,4,5,n
 5
Author: Gopinath Kaliappan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-17 06:40:31

Pre-crement oznacza przyrost na tej samej linii. Post-increment oznacza przyrost po wykonaniu linii.

int j=0;
System.out.println(j); //0
System.out.println(j++); //0. post-increment. It means after this line executes j increments.

int k=0;
System.out.println(k); //0
System.out.println(++k); //1. pre increment. It means it increments first and then the line executes

Jeśli chodzi o Or i operatorów, staje się bardziej interesujące.

int m=0;
if((m == 0 || m++ == 0) && (m++ == 1)) { //false
/* in OR condition if first line is already true then compiler doesn't check the rest. It is technique of compiler optimization */
System.out.println("post-increment "+m);
}

int n=0;
if((n == 0 || n++ == 0) && (++n == 1)) { //true
System.out.println("pre-increment "+n); //1
}

In Array

System.out.println("In Array");
int[] a = { 55, 11, 15, 20, 25 } ;
int ii, jj, kk = 1, mm;
ii = ++a[1]; // ii = 12. a[1] = a[1] + 1
System.out.println(a[1]); //12

jj = a[1]++; //12
System.out.println(a[1]); //a[1] = 13

mm = a[1];//13
System.out.printf ( "\n%d %d %d\n", ii, jj, mm ) ; //12, 12, 13

for (int val: a) {
     System.out.print(" " +val); //55, 13, 15, 20, 25
}

W C++ post / pre-increment zmiennej wskaźnika

#include <iostream>
using namespace std;

int main() {

    int x=10;
    int* p = &x;

    std::cout<<"address = "<<p<<"\n"; //prints address of x
    std::cout<<"address = "<<p<<"\n"; //prints (address of x) + sizeof(int)
    std::cout<<"address = "<<&x<<"\n"; //prints address of x

    std::cout<<"address = "<<++&x<<"\n"; //error. reference can't re-assign because it is fixed (immutable)
}
 5
Author: Uddhav Gautam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-06-08 07:07:10

Krótko:

++i i i++ działa tak samo, jeśli nie piszesz ich w funkcji. Jeśli użyjesz czegoś takiego jak function(i++) lub function(++i), zobaczysz różnicę.

function(++i) mówi pierwszy przyrost i o 1, po tym umieść to i w funkcji z nową wartością.

function(i++) mówi put first i do funkcji po przyroście i o 1.

int i=4;
printf("%d\n",pow(++i,2));//it prints 25 and i is 5 now
i=4;
printf("%d",pow(i++,2));//it prints 16 i is 5 now
 5
Author: GokhanAvci,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-06-08 07:10:26

Można myśleć o wewnętrznej konwersji tego jako wielu wyrażeń ;

  • przypadek 1
i++;

Można to uznać za,

i;
i = i+1;
  • przypadek 2
++i;

Można to uznać za,

i = i+i;
i;
 3
Author: Jeet Parikh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-01-03 15:44:01

A=i++ oznacza, że a Zawiera bieżącą wartość i a = ++i oznacza, że a Zawiera zwiększoną wartość i

 -3
Author: munna,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-17 09:56:02

Oto przykład, aby zrozumieć różnicę

int i=10;
printf("%d %d",i++,++i);

Output: 10 12/11 11 (w zależności od kolejności ewaluacji argumentów funkcji printf, która różni się w zależności od kompilatorów i architektur)

Wyjaśnienie: i++->i jest drukowana, a następnie inkrementowana. (Drukuje 10, ale {[4] } będzie 11) ++i->i wartość zwiększa i drukuje wartość. (Wypisuje 12, a wartość i również 12)

 -6
Author: srinath,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-09 16:29:52