В чем разница между ++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), который демонстрирует то же самое.
причина ++i
можете быть немного быстрее, чем i++
это i++
может потребоваться локальная копия значения i, Прежде чем оно будет увеличено, в то время как ++i
никогда этого не делает. В некоторых случаях некоторые компиляторы по возможности оптимизируют его... но это не всегда возможно, и не все компиляторы делают это.
Я стараюсь не слишком полагаться на оптимизацию компиляторов, поэтому я бы последовал совету Райана Фокса: когда я могу использовать оба, я использую ++i
.
эффективный результат использования любого из них идентичен. Иными словами, цикл будет делать то же самое в обоих случаях.
с точки зрения эффективности, может быть штраф, связанный с выбором i++ над ++i. С точки зрения спецификации языка, использование оператора post-increment должно создать дополнительную копию значения, на которое действует оператор. Это может быть источником дополнительных операций.
однако, вы должны рассмотреть две основные проблемы с предшествующая логика.
современные компиляторы прекрасно. Все хорошие компиляторы достаточно умны, чтобы понять, что он видит целочисленный инкремент в цикле for, и он оптимизирует оба метода для одного и того же эффективного кода. Если использование post-increment над pre-increment фактически заставляет вашу программу работать медленнее, то вы используете Грозный компилятора.
с точки зрения операционного времени-сложность, два метода (даже если копия фактически выполняется) эквивалентны. Количество инструкций, выполняемых внутри цикла, должно значительно доминировать над количеством операций в операции приращения. Поэтому в любом цикле значительного размера штраф метода 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)