17 март 2016 г.

CODE TIPS #3 - Преинкрементирайте брояча във for цикли! (++C)

Когато започнах да пиша код на C++ ми отне известно време да схвана идеята зад for цикъла. Най-странната част беше това i++ накрая. В последствие разбрах, че просто означава "увеличи стойността на променливата i с 1". Супер! Но после открих и ++i , което прави същото, но с една съществена разлика.

Барт инкрементира правилно!


Ако имаме декларирана целочислена променлива i, инициализирана със стойност 0 и следния код:

  1. while (< 5) {
  2. std::cout << i++ << " ";
  3. }

Изходът ще е: 0 1 2 3 4
Ето какво се случва - извеждаме стойността на i и чак след това стойността й се увеличава с 1.

Но пък от друга страна, ако имаме този код вместо първия:

  1. while (< 5) {
  2. std::cout << ++i << " ";
  3. }

Изходът ще е: 1 2 3 4 5

Обяснението е просто - първо стойността на i се увеличава с 1 и след това я извеждаме на конзолата.

Но имайки предвид това как работи for цикъла, пробваме и се убеждаваме, че това няма значение, защото обновяването на брояча се случва след всяко завъртане на цикъла:

  1. // Output: 0 1 2 3 4
  2. for (int i = 0; i < 5; i++) {
  3.     std::cout << i << " ";
  4. }
  5. // Output: 0 1 2 3 4
  6. for (int i = 0; i < 5; ++i) {
  7.     std::cout << i << " ";
  8. }

Значи няма разлика, нали? Е, оказва се, че има!

При случая i++ се създава временна променлива, в която се запаметява сегашната стойност на i, стойността на временната променлива се увеличава с 1 и тази стойност се дава за нова стойност на i. При случая ++i директно се обновява стойността на i, без нуждата от първата инструкция. Тази оптимизация може да се приложи автоматично и в двата случая за примитивни типове, но не и когато използваме итератори например.

Разликата е малка и понякога несъществена, но в по-сложни програми преинкрементирането просто е добър навик.


Няма коментари:

Публикуване на коментар