В языке C, в чем разница между использованием ++i
и i++
, и что следует использовать в блоке инкрементации цикла for
?
++i
увеличит значение i
, а затем вернет увеличенное значение.
i = 1;
j = ++i;
(i равно 2, j равно 2)
i++
увеличит значение i
, но вернет исходное значение, которое i
имело до увеличения.
i = 1;
j = i++;
(i равно 2, j равно 1)
Для цикла for
подходит любой из вариантов. ++i
кажется более распространенным, возможно, потому что именно это используется в K&R.
В любом случае, следуйте рекомендациям "предпочитайте ++i
, а не i++
", и вы не ошибетесь.
Есть пара замечаний относительно эффективности ++i
и i++
. В любом компиляторе, не относящемся к студенческому проекту, разницы в производительности не будет. Вы можете убедиться в этом, посмотрев на сгенерированный код, который будет идентичен.
Вопрос эффективности интересен... вот моя попытка ответа: https://stackoverflow.com/questions/24886/is-there-a-performance-difference-between-i-and-i
Как отмечает On Freund, для объекта C++ все обстоит иначе, поскольку operator++()
- это функция, и компилятор не может знать, оптимизировать ли создание временного объекта для хранения промежуточного значения.
я++ называется Пост инкремент а ++я называется до инкремента.
я++
я
's стоимостью по 1 после операции.Рассмотрим следующий пример:
int i = 1, j;
j = i++;
Здесь значение буквы J = 1
, но я = 2
. Здесь значение " Я "будет назначена" с "сначала, потом" я " будет увеличиваться.
++я
++I
- это пре-инкремента, потому что это увеличивает я
's стоимостью от 1 до операции.
Это означает Дж = я;
будет выполняться после I++
.
Рассмотрим следующий пример:
int i = 1, j;
j = ++i;
Здесь значение с J = 2
, но я = 2
. Здесь ценность " я "будет назначена" с "после" я "incremention " я".
Подобно ++I будет выполняться до буквы
J=Я;`.
На ваш вопрос , которые должны быть использованы в приращения блок для петли? ответ: можно использовать любой.. не'т вопрос. Он выполнит свой цикл же нет. раз.
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++
, заключается в том, что i++
может потребовать локальную копию значения i перед его увеличением, в то время как ++i
никогда этого не делает. В некоторых случаях некоторые компиляторы оптимизируют это, если это возможно... но это не всегда возможно, и не все компиляторы делают это.
Я стараюсь не слишком полагаться на оптимизацию компиляторов, поэтому я бы последовал совету Райана Фокса: когда я могу использовать оба варианта, я использую ++i
.
Они оба прирастить количество. ++я
эквивалентно я = я + 1
.
увеличивает количество до текущего выражения, тогда как
I++` увеличивает количество после выражения.Пример:
int i = 1;
int x = i++; //x is 1, i is 2
int y = ++i; //y is 3, i is 3
Эффективный результат использования либо идентична. Иными словами, цикл будет делать то же самое в обоих случаях.
С точки зрения эффективности, может быть штраф, участвующих в выборе я++ над ++Я. С точки зрения спецификации языка, используя постфиксный оператор должен создать дополнительную копию значения, на которых оператор действует. Это может быть источником дополнительных операций.
Однако, следует рассмотреть две основные проблемы с предыдущей логики.
Современные компиляторы прекрасно. Все хорошие компиляторы достаточно умны, чтобы понять, что он видит целое приращение в цикле for, и это позволит оптимизировать оба способа для той же эффективный код. Если использовать пост-инкремент за пре-инкремент на самом деле вызывает вашу программу медленнее время, тогда вы используете страшные компилятор.
С точки зрения рабочего времени-сложность двух методов (даже если копия есть на самом деле выполняется) эквивалентны. Количество инструкций, выполняемых внутри цикла должны преобладать количество операций в операции инкремента значительно. Поэтому в любом цикле значительных размеров, наказание за метод increment будут массово омрачено выполнения тела цикла. Другими словами, вы гораздо лучше беспокоиться об оптимизации кода в цикле, а не приращение.
На мой взгляд, весь вопрос сводится к выбору предпочтений в стиле. Если вы считаете, что пре-инкремент более читабельным, а затем использовать его. Лично я предпочитаю пост-incrment, но это наверное потому что меня учили, прежде чем я знал что-нибудь об оптимизации.
Это типичный пример преждевременной оптимизации, и как эти проблемы могут отвлечь нас от серьезных проблем в конструкции. Это еще хороший вопрос, однако, поскольку отсутствует единообразие в использовании или консенсуса в "Лучшие практики&.и"
`++я: это пре-инкремент другой пост-инкремент.
: получает элемент, а затем увеличивает его.
++я: я увеличивает и возвращает элемент.Пример:
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 я = 5
, `инт б = ++я
В данном случае, 6 назначается в первую очередь, а затем увеличивается до 7 и так далее.
я++
(операция Постфиксная): назначение и затем увеличивает значение
(ЭГ): int я = 5
, инт б = я++
В данном случае, 5 относится к B и затем с шагом в 6 и так далее.
В случае цикла for: Я++
является в основном используется, потому что обычно мы используем начальное значение я
до увеличения в для петли. Но в зависимости от логики работы программы может меняться.
Этот код может помочь визуализировать различие под другим углом, чем уже написал ответы:
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
Обратите внимание на до и после ситуации.
А за что один из них должен быть использован в приращения блок для петли, я думаю, что лучшее, что мы можем сделать, чтобы принять решение-это использовать хороший пример:
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.
Следующий фрагмент кода иллюстрирует разницу между до и после инкремента и декремента:
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
Я предполагаю, что вы понимаете разницу в семантике сейчас (хотя, честно говоря, я удивляюсь, почему люди спрашивают 'что делает оператор X означает' вопросы на переполнение стека, а не читать, вы знаете, книга или web-учебник или что-то.
Но в любом случае, насколько какой из них использовать, игнорировать вопросы производительности, которые вряд ли важно, даже в C++. Это принцип следует использовать при принятии решения что использовать:
Сказать, что вы имеете в виду в коде.
Если вы Don'т нужно значение до инкремента в своем заявлении, Дон'т использовать эту форму оператор. Это'ы незначительная проблема, но если вы работаете со стилем руководства, который запрещает никто версии в пользу другой совсем (ака кости, возглавляемых гид по стилю), вы должны использовать форме, которая наиболее точно выражает то, что вы пытаетесь сделать.
Что и требовалось доказать, использовать пре-инкремент версии:
for (int i = 0; i != X; ++i) ...
основное отличие это
я++ пост(после инкремента) и
++я заранее (до инкремента)
должность, если
я =1
цикл с шагом как 1,2,3,4,Н -заранее если
я =1
цикл с шагом как 2,3,4,5,Н
Разницу можно понять по этой простой 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
и я++
работает так же, если вы не пишете их в функции. Если вы используете что-то вроде функция(я++)
или функция(++я)
вы можете увидеть разницу.
`функция(++я) - говорит первый увеличить I на 1, после этого поставить это " я " в функции нового значения.
функция (я++) говорит ставить на первое
яв функцию после этого инкремента
я` 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
Предварительно урожая от означает прирост на той же линии. Пост-инкремент означает инкремент после строки выполняет.
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
Когда он приходит с ИЛИ, и операторов, он становится более интересным.
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)
}
Разница лишь порядок операций между инкремент переменной и значение возвращает оператор.
Этот код и его вывод объясняет разницу:
#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
Так что в принципе возвращает++Я
значение после того, как он увеличивается, в то время как `++я возвращать значение, прежде чем он увеличивается. В конце концов, в обоих случаях "я", его ценность увеличивается.
Другой пример:
#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
Различия очевидны, когда возвращаемое значение присваивается другой переменной или когда приращение осуществляется в конкатенации с другими операциями, где преимущество операциям применяется (я++2отличается от
++я2, но
(я++)2и
(я++)2` возвращает то же значение) во многих случаях они взаимозаменяемы. Классическим примером является синтаксис цикла:
for(int i=0; i<10; i++)
имеет тот же эффект
for(int i=0; i<10; ++i)
Чтобы не вносить путаницы между двумя операторами я принял это правило:
Доцент должность оператор ++
по отношению к переменной i
в порядке операции ++
в отношении уступки
Сказал другими словами:
++
до Я
означает приращения должна быть проведена до назначение;++
после я
означает приращение должно осуществляться после назначение:Вы можете думать о внутренней конверсии, что несколько инструкций;
// case 1 :
i++;
/* you can think as,
* i;
* i= i+1;
*/
// case 2
++i;
/* you can think as,
* i = i+i;
* i;
*/