В чем разница между ++i и i++?

В C, в чем разница между использованием ++i и i++ и который должен использоваться в блоке инкрементации цикла for?

752
24 авг. '08 в 8:19
источник поделиться
21 ответ
  • ++i увеличит значение i, а затем вернет увеличенное значение.

     i = 1;
     j = ++i;
     (i is 2, j is 2)
    
  • i++ увеличит значение i, но вернет исходное значение, которое i удерживает до того, как будет увеличено.

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

Для цикла for либо работает. ++i кажется более распространенным, возможно, потому что это то, что используется в K & R.

В любом случае следуйте рекомендациям "предпочитайте ++i по i++", и вы не ошибетесь.

Там пара комментариев относительно эффективности ++i и i++. В любом компиляторе не-студента-проекта разница производительности не будет. Вы можете проверить это, посмотрев сгенерированный код, который будет идентичным.

Вопрос эффективности интересен... здесь моя попытка ответить: есть ли разница в производительности между i++ и ++i в C?

Как отмечает Фрейнд, он отличается for объектом C++, поскольку operator++() является функцией, и компилятор не может знать, чтобы оптимизировать создание временного объекта для хранения промежуточного значения.

935
24 авг. '08 в 8:23
источник

i++ известен как Post Increment, тогда как ++i называется Pre Increment.

i++

i++ - это приращение, потому что после завершения операции увеличивается значение i на 1.

Давайте посмотрим следующий пример:

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

Здесь значение j = 1, но i = 2. Здесь значение i будет назначено на j, затем i будет увеличено.

++i

++i является предварительным приращением, потому что он увеличивает значение i на 1 до операции. Это означает, что j = i; будет выполняться после i++.

Давайте посмотрим следующий пример:

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

Здесь значение j = 2, но i = 2. Здесь значение i будет присвоено j после i приращения i. Аналогично ++i будет выполняться до j=i;.

Для вашего вопроса, который должен использоваться в блоке инкрементации цикла for ? ответ: вы можете использовать любой... не имеет значения. Он выполнит ваш for цикл таким же образом. раз.

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

А также

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

Оба цикла будут производить одинаковый вывод. т.е. 0 1 2 3 4.

Это имеет значение только там, где вы его используете.

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

В этом случае вывод будет 1 2 3 4 5.

155
28 марта '12 в 8:54
источник

Пожалуйста, не беспокойтесь о "эффективности" (скорость, действительно), из которой быстрее. В наши дни у нас есть компиляторы, которые заботятся об этом. Используйте то, что имеет смысл использовать, на основе чего более четко показано ваше намерение.

37
20 сент. '08 в 8:06
источник

++i увеличивает значение, а затем возвращает его.

i++ возвращает значение, а затем увеличивает его.

Это тонкая разница.

Для цикла for используйте ++i, так как он немного быстрее. i++ создаст дополнительную копию, которая просто будет выброшена.

32
24 авг. '08 в 8:21
источник

i++: - В этом сценарии сначала присваивается значение, а затем происходит увеличение.

++i: - В этом сценарии сначала выполняется приращение, а затем назначается значение

Ниже представлена визуализация изображения, а также вот хорошее практическое видео (http://www.youtube.com/watch?v=lrtcfgbUXm4), которое демонстрирует то же самое.

enter image description here

23
25 июля '13 в 10:42
источник

Причина ++i может быть немного быстрее, чем i++ заключается в том, что i++ может потребоваться локальная копия значения i до того, как она будет увеличена, а ++i никогда не будет. В некоторых случаях некоторые компиляторы оптимизируют его, если это возможно... но это не всегда возможно, и не все компиляторы делают это.

Я стараюсь не слишком полагаться на оптимизацию компиляторов, поэтому I' d следует совету Ryan Fox: когда i может использовать оба варианта, i использует ++i.

21
24 авг. '08 в 9:00
источник

Эффективный результат использования либо идентичен. Другими словами, цикл будет делать то же самое в обоих случаях.

С точки зрения эффективности, может быть наказание за выбор i++ по сравнению с ++i. С точки зрения спецификации языка использование оператора post-increment должно создать дополнительную копию значения, на котором действует оператор. Это может быть источником дополнительных операций.

Однако вы должны рассмотреть две основные проблемы с предыдущей логикой.

  1. Современные компиляторы великолепны. Все хорошие компиляторы достаточно умны, чтобы понять, что он видит целочисленное приращение в цикле for, и оптимизирует оба метода к одному и тому же эффективному коду. Если использование пост-инкремента по сравнению с предварительным приращением фактически заставляет вашу программу работать медленнее, вы используете ужасный компилятор.

  2. С точки зрения сложности времени выполнения, два метода (даже если копия фактически выполняется) эквивалентны. Количество команд, выполняемых внутри цикла, должно значительно превышать количество операций в операции увеличения. Следовательно, в любом цикле значительного размера штраф за метод инкремента будет значительно затенен выполнением тела цикла. Другими словами, вам гораздо лучше беспокоиться об оптимизации кода в цикле, а не приращении.

На мой взгляд, весь вопрос просто сводится к предпочтению стиля. Если вы считаете, что pre-increment является более читаемым, используйте его. Лично I предпочитает post-incrment, но это, вероятно, потому, что это было то, что I преподавалось до того, как I ничего не знал об оптимизации.

Это типичный пример преждевременной оптимизации, и подобные проблемы могут отвлечь нас от серьезных проблем в дизайне. Однако по-прежнему возникает хороший вопрос, потому что нет единообразия в использовании или консенсусе в "лучшей практике".

13
07 мая '11 в 0:36
источник

Они оба увеличивают число. ++i эквивалентно я = я + 1.

i++ и ++i очень похожи, но не совсем одинаковы. Оба увеличивают число, но ++i увеличивает число перед вычислением текущего выражения, тогда как i++ увеличивает число после вычисления выражения.

Пример:

int i = 1;
int x = i++; //x is 1, i is 2
int y = ++i; //y is 3, i is 3
12
19 февр. '18 в 8:04
источник

++i - предварительный приращение, другое - пост-приращение

i++: получает элемент, а затем увеличивает его.
++i: увеличивает i , а затем возвращает элемент

Пример:

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

Вывод:

i: 0
i++: 0
++i: 2
6
17 сент. '13 в 15:23
источник

++i (операция префикса): увеличивает и затем присваивает значение
(например): int i = 5, int b = ++i< br> В этом случае 6 сначала назначается b, а затем увеличивается до 7 и так далее.

i++ (операция Postfix): назначает и затем увеличивает значение
(например): int i = 5, int b = i++< br> В этом случае 5 сначала назначается b, а затем увеличивается до 6 и так далее.

Включение цикла for : i++ в основном используется, потому что обычно мы используем начальное значение i до увеличения в for . Но в зависимости от вашей программной логики это может различаться.

6
13 мая '16 в 8:50
источник

i++ и ++i

Этот небольшой код может помочь визуализировать разницу под другим углом, чем уже опубликованные ответы:

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);

Результат:

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

Обратите внимание на ситуации до и после.

для цикла

Что касается того, какой из них следует использовать в блоке приращения цикла for, я думаю, что лучшее, что мы можем сделать, чтобы принять решение, - это использовать хороший пример:

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);

Результат:

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

Я не знаю о вас, но я не вижу никакой разницы в его использовании, по крайней мере, в цикле for.

5
19 февр. '18 в 23:51
источник

Разницу можно понять с помощью этого простого кода 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
13 сент. '17 в 0:13
источник

Главное отличие

  • i++ Post (после увеличения) и
  • ++i Pre (до приращения)

    • отправьте, если i =1 цикл увеличивается как 1,2,3,4,n
    • предварительно, если i =1 цикл увеличивается как 2,3,4,5,n
5
13 мая '16 в 9:00
источник

Я предполагаю, что теперь вы понимаете разницу в семантике (хотя, честно говоря, I задаются вопросом, почему люди спрашивают "что означает оператор X означает" вопросы о переполнении стека ", а не читают, знаете ли, книгу или веб-учебник или что-то еще.

Но в любом случае, насколько можно использовать, игнорировать вопросы производительности, которые вряд ли важны даже в C++. Это принцип, который вы должны использовать при принятии решения о том, что использовать:

Скажите, что вы имеете в виду в коде.

Если вам не нужно значение-до-increment в вашем заявлении, не используйте эту форму оператора. Это второстепенная проблема, но если вы не работаете с руководством по стилю, которое запрещает одну версию в пользу другого вообще (так называемое руководство по стилю с костью), вы должны использовать форму, которая наиболее точно выражает то, что вы пытаетесь сделать.

QED, используйте предварительную инкрементную версию:

for (int i = 0; i != X; ++i) ...
5
04 авг. '11 в 20:20
источник

В ближайшее время: ++i и i++ работают одинаково, если вы не записываете их в функцию. Если вы используете что-то вроде функции (i++) или функции (++i), вы можете увидеть разницу.

function [++i) говорит о первом приращении i на 1, после чего добавьте этот i в функцию с новым значением.

function [i++) говорит, что сначала добавьте i в функцию после этого приращения i на 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
4
22 авг. '13 в 20:25
источник

Pre-crement означает приращение в той же строке. Пост-приращение означает приращение после выполнения строки.

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

Когда дело доходит с операциями OR, AND, это становится более интересным.

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
}

В массиве

        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
        }

В C++ пост/предварительный приращение указательной переменной

#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)
}
4
29 сент. '17 в 19:49
источник

Следующий фрагмент кода C иллюстрирует разницу между операторами pre и post increment and decment:

int i; int j;

//Принудительные операторы

я = 1;

j = ++i;// i теперь 2, j также 2

j = i++;// i теперь 3, j равно 2

4
01 окт. '17 в 18:58
источник

Единственная разница - это порядок операций между приращением переменной и значением, которое возвращает оператор.

Этот код и его вывод объясняют разницу:

#include<stdio.h>

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

Выход:

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

Таким образом, в основном ++i возвращает значение после его увеличения, в то время как ++i возвращает значение до его увеличения. В конце, в обоих случаях значение i будет увеличено.

Другой пример:

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

Выход:

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

Много раз нет разницы

Различия очевидны, когда возвращаемое значение присваивается другой переменной или когда приращение выполняется в конкатенации с другими операциями, где применяется приоритет операций (i++*2 отличается от ++i*2, но (i++)*2 и (++i)*2 возвращает одно и то же значение) во многих случаях они взаимозаменяемы. Классическим примером является синтаксис цикла for:

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

имеет тот же эффект

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

Правило помнить

Чтобы не путать два оператора, я принял это правило:

Свяжите позицию оператора ++ относительно переменной i с порядком операции ++ относительно присвоения

Сказал другими словами:

  • ++ прежде чем i означает, что приращение должно быть выполнено перед присваиванием;
  • ++ после i означает, что приращение должно выполняться после присваивания:
1
27 февр. '19 в 20:49
источник

Вы можете думать о внутреннем преобразовании этого как о множественных утверждениях;

// case 1 :

i++;

/* you can think as,
 * i;
 * i= i+1;
 */

// case 2

++i;

/* you can think as,
 * i = i+i;
 * i;
 */
-1
06 авг. '18 в 12:25
источник

a = i++ означает a содержит текущее значение я a = ++i означает a содержит увеличенное значение i

-3
22 янв. '13 в 12:13
источник

Вот пример, чтобы понять разницу

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

output: 10 12/11 11 (в зависимости от порядка оценки аргументов функции printf, которая зависит от компиляторов и архитектур)

Объяснение: i++i печатается, а затем увеличивается. (Отпечатки 10, но i станет 11). ++ii значение увеличивает и печатает значение. (Отпечатки 12 и значение i также 12)

-5
14 нояб. '13 в 16:01
источник

Посмотрите другие вопросы по меткам или Задайте вопрос