Подтвердить что ты не робот

#ИМЯ?

Возможный дубликат:
Есть ли разница в производительности между я ++ и ++ я на С++?

Есть ли причина, по которой некоторые программисты пишут ++i в нормальном цикле, а не пишут i++?

4b9b3361

Ответ 1

Для целых чисел нет разницы между пре-и пост-приращением.

Если i является объектом нетривиального класса, тогда ++i обычно предпочтительнее, поскольку объект изменяется и затем оценивается, тогда как i++ изменяется после оценки, поэтому требуется копия.

Ответ 2

++i немного более эффективен из-за его семантики:

++i;  // Fetch i, increment it, and return it
i++;  // Fetch i, copy it, increment i, return copy

Для индексов типа int коэффициент усиления эффективности минимален (если таковой имеется). Для итераторов и других объектов с более тяжелым весом избежать этой копии может быть реальным выигрышем (особенно если тело цикла не содержит большой работы).

В качестве примера рассмотрим следующий цикл, используя теоретический класс BigInteger, предоставляющий произвольные целые числа точности (и, следовательно, некоторые векторные объекты):

std::vector<BigInteger> vec;
for (BigInteger i = 0; i < 99999999L; i++) {
  vec.push_back(i);
}

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

Ответ 3

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

Ответ 4

С целыми числами это предпочтение.

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

Если создание этой копии является дорогостоящей операцией, вы платите этот расход один раз за каждый раз, когда вы проходите цикл, без всякой причины.

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

Ответ 5

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

Ответ 6

Никакой компилятор, имеющий свой вес в соли, будет работать по-разному между

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

и

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

++ я и я ++ имеют ту же стоимость. Единственное отличие состоит в том, что возвращаемое значение ++ я равно я + 1, тогда как возвращаемое значение я ++ - это i.

Итак, для тех, кто предпочитает ++ i, вероятно, нет действительного обоснования, а только личных предпочтений.

EDIT: Это неправильно для классов, как сказано в каждом другом сообщении. я ++ будет генерировать копию, если я является классом.

Ответ 7

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

Foo& operator++()
{
    some_member.increase();
    return *this;
}

Foo operator++(int dummy_parameter_indicating_postfix)
{
    Foo copy(*this);
    ++(*this);
    return copy;
}

Как вы можете видеть, префиксная версия просто изменяет объект и возвращает его по ссылке.

Постфиксная версия, с другой стороны, должна сделать копию до фактического приращения, а затем эта копия будет скопирована обратно на вызывающего по значению. Из исходного кода очевидно, что постфиксная версия должна работать больше, потому что она включает в себя вызов префиксной версии: ++(*this);

Для встроенных типов это не имеет никакого значения, пока вы отбрасываете это значение, то есть до тех пор, пока вы не вставляете ++i или i++ в большее выражение, такое как a = ++i или b = i++.

Ответ 8

Личные предпочтения.

Обычно. Иногда это имеет значение, но не для того, чтобы казаться рывком здесь, но если вы должны спросить, это, вероятно, не делает.

Ответ 9

когда вы используете postfix, он создает экземпляр для большего количества объектов в памяти. Некоторые говорят, что лучше использовать суффикс-оператор для цикла