В C, в чем разница между использованием ++i
и i++
и который должен использоваться в блоке инкрементации цикла for
?
C: В чем разница между ++i и i++?
Ответ 1
-
++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++()
является функцией, и компилятор не может знать, чтобы оптимизировать создание временного объекта для хранения промежуточного значения.
Ответ 2
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
.
Ответ 3
Пожалуйста, не беспокойтесь о "эффективности" (скорость, действительно), из которой быстрее. В наши дни у нас есть компиляторы, которые заботятся об этом. Используйте то, что имеет смысл использовать, на основе чего более четко показано ваше намерение.
Ответ 4
++i
увеличивает значение, а затем возвращает его.
i++
возвращает значение, а затем увеличивает его.
Это тонкая разница.
Для цикла for используйте ++i
, так как он немного быстрее. i++
создаст дополнительную копию, которая просто будет выброшена.
Ответ 5
i++
: в этом сценарии сначала присваивается значение, а затем происходит приращение.
++i
: в этом сценарии сначала выполняется приращение, а затем присваивается значение
Ниже приведена визуализация изображения, а также хорошее практическое видео, демонстрирующее то же самое.
Ответ 6
Причина ++i
может быть немного быстрее, чем i++
заключается в том, что i++
может потребоваться локальная копия значения i до того, как она будет увеличена, а ++i
никогда не будет. В некоторых случаях некоторые компиляторы оптимизируют его, если это возможно... но это не всегда возможно, и не все компиляторы делают это.
Я стараюсь не слишком полагаться на оптимизацию компиляторов, поэтому I' d следует совету Ryan Fox: когда i может использовать оба варианта, i использует ++i
.
Ответ 7
Эффективный результат использования либо идентичен. Другими словами, цикл будет делать то же самое в обоих случаях.
С точки зрения эффективности, может быть наказание за выбор i++ по сравнению с ++i. С точки зрения спецификации языка использование оператора post-increment должно создать дополнительную копию значения, на котором действует оператор. Это может быть источником дополнительных операций.
Однако вы должны рассмотреть две основные проблемы с предыдущей логикой.
-
Современные компиляторы великолепны. Все хорошие компиляторы достаточно умны, чтобы понять, что он видит целочисленное приращение в цикле for, и оптимизирует оба метода к одному и тому же эффективному коду. Если использование пост-инкремента по сравнению с предварительным приращением фактически заставляет вашу программу работать медленнее, вы используете ужасный компилятор.
-
С точки зрения сложности времени выполнения, два метода (даже если копия фактически выполняется) эквивалентны. Количество команд, выполняемых внутри цикла, должно значительно превышать количество операций в операции увеличения. Следовательно, в любом цикле значительного размера штраф за метод инкремента будет значительно затенен выполнением тела цикла. Другими словами, вам гораздо лучше беспокоиться об оптимизации кода в цикле, а не приращении.
На мой взгляд, весь вопрос просто сводится к предпочтению стиля. Если вы считаете, что pre-increment является более читаемым, используйте его. Лично I предпочитает post-incrment, но это, вероятно, потому, что это было то, что I преподавалось до того, как I ничего не знал об оптимизации.
Это типичный пример преждевременной оптимизации, и подобные проблемы могут отвлечь нас от серьезных проблем в дизайне. Однако по-прежнему возникает хороший вопрос, потому что нет единообразия в использовании или консенсусе в "лучшей практике".
Ответ 8
Они оба увеличивают число. ++i
эквивалентно 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
Ответ 9
++i
: предварительное увеличение, другое - ++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
Ответ 10
++i
(операция с префиксом): увеличивает, а затем назначает значение
(например): int я = 5
, int b = ++i
В этом случае сначала назначается 6 для b, а затем увеличивается до 7 и так далее.
i++
(операция постфикса): присваивает, а затем увеличивает значение
(например): int я = 5
, int b = i++
В этом случае 5 назначается сначала b, а затем увеличивается до 6 и так далее.
Incase для цикла for: i++
в основном используется, потому что, как правило, мы используем начальное значение i
прежде чем увеличивать цикл for. Но в зависимости от логики вашей программы это может варьироваться.
Ответ 11
Я предполагаю, что теперь вы понимаете разницу в семантике (хотя, честно говоря, I задаются вопросом, почему люди спрашивают "что означает оператор X означает" вопросы о переполнении стека ", а не читают, знаете ли, книгу или веб-учебник или что-то еще.
Но в любом случае, насколько можно использовать, игнорировать вопросы производительности, которые вряд ли важны даже в C++. Это принцип, который вы должны использовать при принятии решения о том, что использовать:
Скажите, что вы имеете в виду в коде.
Если вам не нужно значение-до-increment в вашем заявлении, не используйте эту форму оператора. Это второстепенная проблема, но если вы не работаете с руководством по стилю, которое запрещает одну версию в пользу другого вообще (так называемое руководство по стилю с костью), вы должны использовать форму, которая наиболее точно выражает то, что вы пытаетесь сделать.
QED, используйте предварительную инкрементную версию:
for (int i = 0; i != X; ++i) ...
Ответ 12
Главное отличие
- i++ Post (после увеличения) и
++i Pre (до приращения)
- отправьте, если
i =1
цикл увеличивается как1,2,3,4,n
- предварительно, если
i =1
цикл увеличивается как2,3,4,5,n
Ответ 13
Разницу можно понять с помощью этого простого кода 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;
Ответ 14
Следующий фрагмент кода C иллюстрирует различие между операторами увеличения и уменьшения до и после операции:
int i;
int j;
Операторы приращения:
i = 1;
j = ++i; // i is now 2, j is also 2
j = i++; // i is now 3, j is 2
Ответ 15
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.
Ответ 16
Коротко:
++i
и i++
работают одинаково, если вы не записываете их в функцию. Если вы используете что-то вроде function(i++)
или function(++i)
вы можете увидеть разницу.
function(++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
Ответ 17
Предварительная обработка означает приращение на той же строке. Постинкремент означает приращение после выполнения строки.
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++ 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)
}
Ответ 18
Единственная разница - это порядок операций между приращением переменной и значением, которое возвращает оператор.
Этот код и его вывод объясняют разницу:
#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
означает, что приращение должно выполняться после присваивания:
Ответ 19
Вы можете думать о внутреннем преобразовании этого как о множественных утверждениях;
// case 1 :
i++;
/* you can think as,
* i;
* i= i+1;
*/
// case 2
++i;
/* you can think as,
* i = i+i;
* i;
*/
Ответ 20
a = i++ означает a содержит текущее значение я a = ++i означает a содержит увеличенное значение i
Ответ 21
Вот пример, чтобы понять разницу
int i=10;
printf("%d %d",i++,++i);
output: 10 12/11 11
(в зависимости от порядка оценки аргументов функции printf
, которая зависит от компиляторов и архитектур)
Объяснение: i++
→ i
печатается, а затем увеличивается. (Отпечатки 10, но i
станет 11). ++i
→ i
значение увеличивает и печатает значение. (Отпечатки 12 и значение i
также 12)