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

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

20 ответов


  • ++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.

в любом случае, следуйте рекомендациям " prefer ++i над


i++ называется Пост Инкремент, тогда как ++i называется Pre Increment.

i++

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

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

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

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

++i

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

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

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

здесь значение j = 2 но i = 2. Здесь значение i назначается j после i incremention из 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.


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


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

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

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

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


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

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

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

enter image description here


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

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


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

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

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

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

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

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

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


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

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

пример :

int i = 1;
int x = i++; //x is 1, i is 2
int y = ++i; //y is 3, i is 3

++i является pre-increment другой является post-increment

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

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

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

Incase for loop: I++ в основном используется потому что обычно мы используем начальное значение i перед увеличением цикла for.Но в зависимости от логики работы программы может меняться.


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

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

сказать, что вы имеете в виду в коде.

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

QED, используйте версию pre-increment:

for (int i = 0; i != X; ++i) ...

разница может быть понята этим простым кодом 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;

основное отличие -

  • Я++ пост(После Инкремента) и
  • ++Я заранее (До Инкремента)

    • почтой i =1 цикл увеличивается как 1,2,3,4,n
    • pre если i =1 цикл увеличивается как 2,3,4,5,n

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

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

функция (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

Pre-crement означает инкремент на той же строке. Post-increment означает увеличение после выполнения строки.

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 и операторами, он становится более интересным.

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++ post / pre-increment переменной указателя

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

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

int i; инт Дж;

/ операторов/ инкремент

i = 1;

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

j = i++; / / i теперь 3, j-2


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.


вы можете думать о внутреннем преобразовании этого как несколько инструкций;

// case 1 :

i++;

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

// case 2

++i;

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

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


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

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

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

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