Яка різниця між ++ $ i та $ i ++ у PHP?


Відповіді:


96

++$iє попереднім збільшенням, тоді як $i++після збільшенням.

  • попереднє збільшення: iспочатку збільште змінну, а потім скасуйте посилання.
  • післяінкремент: де-посилання, а потім інкремент i

"Скористайтеся тим фактом, що PHP дозволяє виконувати постінкремент ($ i ++) та попередній інкремент (++ $ i). Значення те саме, поки ви не пишете нічого на зразок $ j = $ i ++, однак попереднє збільшення майже на 10% швидше, а це означає, що вам слід перейти з пост- на попереднє збільшення, коли у вас є можливість, особливо в щільних циклах і особливо якщо ви педантично ставитеся до мікрооптимізацій! " - TuxRadar

Для подальшого роз'яснення, післяінкрементація в PHP була задокументована як зберігання тимчасової змінної, яка приписує цим 10% накладних витрат порівняно з попередньою інкрементацією.


6
Це загальне емпіричне правило, або це специфічно для PHP.
Zoidberg

1
... джерело вказано в моїй відповіді. Я сам цього не перевіряв ... Думаю, міг би, подивившись на вихідний код PHP, хоча ...
jldupont

3
Я б не узагальнював якусь іншу мову.
jldupont

3
Збільшення швидкості попереднього приросту є специфічним для PHP через те, що після приросту створюється тимчасова змінна, що створює накладні витрати.
Кори Баллу

4
@knittl Пам'ятайте, що це 10% від ( дуже сподіваємося) дуже швидкої операції :)
jensgram

68

++$iзростає $i, але оцінює значення $i+1 $i++приростів $i, але оцінює старе значення $i.

Ось приклад:

$i = 10;
$a = $i++;
// Now $a is 10, and $i is 11

$i = 10;
$a = ++$i;
// Now $a is 11, and $i is 11

Іноді за використання є невелика вартість попередньої підготовки $i++. Дивіться, коли ви робите щось подібне

$a = $i++;

Ви справді робите це:

$temporary_variable = $i;
$i=$i+1;
$a=$temporary_variable;

4
Це краща відповідь. Загальне узагальнення того, що це робить без прикладів коду, безглуздо. Прихильність до таких відповідей, швидше за все, мають ті, хто вже знає, як це працює, і, отже, думає, що це чудові відповіді.
Джеймс,

Я впевнений, що на нижчому рівні є щось більше, тому це питання може бути спірним. Але навіщо PHP потрібен тимчасовий var? Чому ні: $ a = $ i; $ i = $ i + 1;
Тейлор Венс,

@Taylor, це чудове питання! Спробуйте замінити $ i таким викликом функції: $a=func()++і запитайте себе, як ви могли переписати його без ++ та не викликаючи func () більше одного разу.
Шалом Креймер

43

++$i - це попереднє збільшення

  1. $i збільшується
  2. повертається нове значення

$i++ - це постінкрементація

  1. значення $iскопійованого до внутрішньої тимчасової змінної
  2. $i збільшується
  3. $iповертається внутрішня копія старого значення


11

в цьому випадку немає різниці:

for($i = 0;$i<3;++$i)var_dump $i;
/*
int(0)
int(1)
int(2)
*/
for($i = 0;$i<3;$i++)var_dump $i;
/*
int(0)
int(1)
int(2)
*/

але:

for($i = 0;$i<3; $j = ++$i )var_dump($j);
/*
NULL
int(1)
int(2)
*/
for($i = 0;$i<3; $j = $i++ )var_dump($j);
/*
NULL
int(0)
int(1)
*/

Це корисно, здається, приріст префіксу найменше дивує. Я зараз перейду на постійне використання префіксного приросту.
CMCDragonkai

8

цей приклад просто пояснює

<?php 

$x = 10;  

echo $x++. ' '.$x;  // the result is 10 and 11

echo '<br>';

$y = 10;

echo ++$y. ' ' .$y; // the result is 11 and 11

// so the  $x++ is not showing +1 at first but the next time
// and the ++y is showing +1 first time but not increasing next

Дякую за простий приклад. Тепер я розумію.
Прадіта

7

Різниця полягає в тому: ++$iбуде збільшувати $iзмінну і повертати оновлене значення, тоді як $i++повертатиме початкове значення, тому збільшуйте його.

$prefix = 1;
$postfix = 1;
echo ++$prefix;   // 2
echo $postfix++;  // 1


4

Інший спосіб розглянути приріст до і після - це скорочення для поєднання 2-х тверджень.

Попереднє збільшення

// long form
$y = $y + 1;
$x = $y; // any statement using $y

// shorthand
$x = ++$y; // the same statement using $y

Післяінкрементне

// long form
$x = $y; // any statement using $y
$y = $y + 1;

// shorthand
$x = $y++; // the same statement using $y

4

$ i ++ відомий як постінкремент. Він збільшує значення $ i лише після того, як спочатку призначив початкове значення $ i $ j.

++ $ i відомий як попереднє збільшення. Він збільшує значення $ i перед тим, як присвоїти значення $ j, тому оновлене значення $ i буде призначене $ j.

Отже,

$i = 4;
$j = $i++;
// Now, $i = 5 and $j = 4

$i = 4;
$j = ++$i;
// Now, $i = 5 and $j = 5

Ці теорії застосовуються подібним чином і для зменшення.

Сподіваюся, це допомагає!


3

Це, мабуть, найкраще проілюстровано на прикладі ...

Після збільшення:

$zero = 0;
$n = $zero++; //$n is zero

Попереднє збільшення:

$zero = 0;
$n = ++$zero; //$n is one

3

Коротка відповідь:

  • Префікс збільшує значення і повертає збільшене значення
  • Postfix збільшує значення і повертає значення до того, як воно було збільшено
  • Префікс швидший

Довга відповідь: Якщо ви трохи подумаєте над тим, як би їх реалізувати самостійно, ви, мабуть, зрозумієте, чому префікс швидший. По правді кажучи, постфікс насправді (часто) реалізується за допомогою префікса:

const T T::operator ++ (int) // postfix
    {
    T orig(*this);
    ++(*this); // call prefix operator
    return (orig);
    }

Уникайте постфіксу, якщо у вас немає конкретної причини цього не робити. Різниця в швидкості може бути досить великою для складних типів даних.

Я насправді шукав це кілька днів тому. Ось моє джерело.


3

Основною метою оператора збільшення після виправлення є використання, як це:

while(*condition*)
    $array[$i++] = $something;

Це дуже елегантний спосіб обійти деякі ітерації масиву. Зламатися:

  1. Елементу масиву, індексованому $ i, буде призначено змінну $ something
  2. Змінна $ i буде збільшена
  3. Ітерація закінчується, стан буде перевірено

У всіх інших випадках слід використовувати префіксний оператор. Це робить код набагато чіткішим (Ви можете бути впевнені, що Ви вже працюєте зі збільшеним значенням певної змінної).


Проголосував за рекомендацію використовувати префікс, якщо постфікс не є суворо необхідним.
developerbmw

0

Я провів такий код, щоб перевірити, чи ++ $ i на 10% швидший за $ i ++. Я визнаю, що код не має стабільного результату, але навіть тоді я мав би принаймні бачити деякі цифри близько 10%. Найвищий показник, який я отримав, був приблизно 4-4,5%.

<?php

$randomFloat = rand(0, 10) / 10;

$before1 = microtime(true);

for($i=0; $i <1000000; ++$i){
    $rand = (rand(0, 10) / 10) * (rand(0, 10) / 10);
}

$after1 = microtime(true);
echo 'it took '.($after1-$before1) . ' seconds fot ++$i<br />';

$before2 = microtime(true);

for($i=0; $i <1000000; $i++){
    $rand = (rand(0, 10) / 10) * (rand(0, 10) / 10);
}

$after2 = microtime(true);
echo 'it took '.($after2-$before2) . ' seconds fot $i++<br /><br />';

echo '++$i is '.((($after1-$before1)*100)/($after2-$before2)-100).'% faster than $i++';

-1

Обидва оператори все ще роблять те, що передбачає їх синтаксис: збільшувати. Незалежно від префікса або постфікса, змінну обов’язково збільшать на 1. Різниця між цими двома полягає у їх повернутих значеннях.

1. Інкремент префіксу повертає значення змінної після її збільшення.

2. З іншого боку, найбільш часто використовуваний приріст постфіксу повертає значення змінної до того, як вона була збільшена.

// Prefix increment

let prefix = 1;
console.log(++prefix); // 2

console.log(prefix); // 2

// Postfix increment

let postfix = 1;

console.log(postfix++); // 1

console.log(postfix); // 2

Щоб запам’ятати це правило , я думаю про синтаксис цих двох. Коли хтось вводить приріст префіксу, каже ++ x. Тут важлива позиція ++. Сказати ++ x означає спочатку збільшити (++), а потім повернути значення x, таким чином, ми маємо ++ x. Інкремент постфіксу працює навпаки. Сказати x ++ означає повернути значення x спочатку, а потім збільшити (++) його після, таким чином x ++.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.