Jaka jest różnica między ++ $ i a $ i ++ w PHP?


Odpowiedzi:


96

++$ijest preinkrementacja, podczas gdy $i++post-inkrementacja.

  • preinkrementacja: inajpierw inkrementuj zmienną, a następnie usuwaj referencje.
  • post-inkrementacja: usuwanie referencji, a następnie inkrementacja i

„Skorzystaj z faktu, że PHP umożliwia post-inkrementację ($ i ++) i preinkrementację (++ $ i). Znaczenie jest takie samo, o ile nie piszesz czegoś takiego jak $ j = $ i ++ preinkrementacja jest prawie 10% szybsza, co oznacza, że ​​powinieneś przełączyć się z post-inkrementacji na preinkrementację, kiedy masz taką możliwość, zwłaszcza w ciasnych pętlach, a zwłaszcza jeśli pedantycznie podchodzisz do mikro-optymalizacji! ” - TuxRadar

Dla dalszego wyjaśnienia, post-inkrementacja w PHP została udokumentowana jako przechowywanie tymczasowej zmiennej, która przypisuje to 10% narzut w porównaniu z preinkrementacją.


6
Czy jest to ogólna zasada, czy jest to specyficzne dla PHP.
Zoidberg

1
... źródło jest wymienione w mojej odpowiedzi. Sam tego nie sprawdziłem ... Myślę, że mógłbym spojrzeć na kod źródłowy PHP ...
jldupont

3
Sam nie uogólniałbym na inny język.
jldupont

3
Zwiększenie szybkości preinkrementacji jest specyficzne dla PHP ze względu na fakt, że post-inkrementacja tworzy tymczasową zmienną, tworząc narzut.
Corey Ballou

4
@knittl Pamiętaj, że jest to 10% (można mieć nadzieję) bardzo szybkiej operacji :)
jensgram

68

++$izwiększa $i, ale szacuje do wartości $i+1 $i++przyrostów $i, ale oblicza do starej wartości $i.

Oto przykład:

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

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

Czasami istnieje niewielki koszt wykonania $i++. Widzisz, kiedy robisz coś takiego

$a = $i++;

Naprawdę to robisz:

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

4
To jest lepsza odpowiedź. Ogólne uogólnianie tego, co robi to bez przykładów kodu, jest bezcelowe. Głosy za takimi odpowiedziami prawdopodobnie pochodzą od tych, którzy już wiedzą, jak to działa, i dlatego uważają, że są to świetne odpowiedzi.
James,

Jestem pewien, że na niższym poziomie jest coś więcej, więc to pytanie może być dyskusyjne. Ale dlaczego PHP miałoby potrzebować zmiennej tymczasowej? Dlaczego nie: $ a = $ i; $ i = $ i + 1;
Taylor Vance

@Taylor, to świetne pytanie! Spróbuj zamienić $ i na takie wywołanie funkcji: $a=func()++i zadaj sobie pytanie, jak można by to przepisać bez ++ i bez wywoływania func () więcej niż raz.
Shalom Craimer

43

++$i jest preinkrementacją

  1. $i jest zwiększana
  2. zwracana jest nowa wartość

$i++ jest post-inkrementacyjny

  1. wartość $iskopiowana do wewnętrznej zmiennej tymczasowej
  2. $i jest zwiększana
  3. zwracana $ijest wewnętrzna kopia starej wartości


11

w tym przypadku nie ma różnicy:

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)
*/

ale:

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)
*/

Jest to przydatne, najmniejszym zaskoczeniem wydaje się być przyrost przedrostka. Zamierzam teraz przełączyć się na zawsze używanie przyrostu prefiksu.
CMCDragonkai

8

ten przykład elplains jest prosty

<?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

Dziękuję za prosty przykład. Teraz rozumiem.
Praditha

7

Różnica jest następująca: ++$izwiększy $izmienną i zwróci zaktualizowaną wartość, podczas gdy $i++zwróci oryginalną wartość, więc ją zwiększy.

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

5

Aby wyjaśnić punkt widzenia jlduponta:

$i = 1;
$x = $i++;
echo $x; // prints 1
$x = ++$i;
echo $x; // prints 3

4

Innym sposobem spojrzenia na inkrementację przed i po jest to, że jest to skrót łączący 2 stwierdzenia.

Wstępne zwiększanie

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

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

Postinkrementacja

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

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

4

$ i ++ jest znane jako post-inkrementacja. Zwiększa wartość $ i dopiero po przypisaniu pierwotnej wartości $ i do $ j.

++ $ i jest znane jako preinkrementacja. Zwiększa wartość $ i przed przypisaniem wartości do $ j, więc zaktualizowana wartość $ i zostanie przypisana do $ j.

W związku z tym,

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

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

Teorie te stosują się w podobny sposób również do dekrementacji.

Mam nadzieję że to pomoże!


3

Najlepiej ilustruje to przykład ...

Post-inkrementacja:

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

Pre-inkrementacja:

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

3

Krótka odpowiedź:

  • Prefiks zwiększa wartość i zwraca zwiększoną wartość
  • Postfix zwiększa wartość i zwraca wartość sprzed jej zwiększenia
  • Prefiks jest szybszy

Długa odpowiedź: Jeśli się trochę nad tym zastanowisz, jak sam byś je zaimplementował, prawdopodobnie zdasz sobie sprawę, dlaczego prefiks jest szybszy. Prawdę mówiąc, postfix jest faktycznie (często) implementowany przy użyciu przedrostka:

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

Unikaj Postfix, chyba że masz konkretny powód, aby tego nie robić. W przypadku złożonych typów danych różnica w szybkości może być dość duża.

Sprawdziłem to kilka dni temu. Oto moje źródło.


3

Głównym celem operatora inkrementacji po naprawie jest użycie w następujący sposób:

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

Jest to bardzo elegancki sposób na obejście niektórych iteracji tablic. Awaria:

  1. Zmienna $ coś zostanie przypisane do elementu tablicy indeksowanego przez $ i
  2. Zmienna $ i zostanie zwiększona
  3. Iteracja dobiegła końca, stan zostanie sprawdzony

We wszystkich innych przypadkach należy użyć operatora prefiksu. Dzięki temu kod jest dużo bardziej przejrzysty (możesz być pewien, że już pracujesz z inkrementowaną wartością danej zmiennej).


Głosowano za zaleceniem użycia prefiksu, chyba że jest to bezwzględnie potrzebny.
developerbmw

0

Uruchomiłem następujący kod, aby sprawdzić, czy ++ $ i jest o 10% szybsze niż $ i ++. Przyznaję, kod nie ma stabilnego wyniku, ale nawet wtedy powinienem był przynajmniej zobaczyć kilka liczb w pobliżu 10%. Najwyższy, jaki uzyskałem, wynosił około 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

Oba operatory nadal robią to, co implikuje ich składnia: zwiększać. Niezależnie od przedrostka lub przyrostka, zmienna z pewnością zostanie zwiększona o 1. Różnica między nimi polega na ich wartościach zwracanych.

1. Przyrost przedrostka zwraca wartość zmiennej po jej zwiększeniu.

2. Z drugiej strony, częściej stosowany przyrost przyrostka zwraca wartość zmiennej, zanim została zwiększona.

// 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

Aby zapamiętać tę regułę , myślę o składni tych dwóch. Kiedy wpisuje się przyrost prefiksu, mówi się ++ x. Ważna jest tutaj pozycja ++. Powiedzenie ++ x oznacza najpierw inkrementację (++), a następnie zwrócenie wartości x, więc mamy ++ x. Przyrost przyrostka działa odwrotnie. Powiedzenie x ++ oznacza najpierw zwrócenie wartości x, a następnie zwiększenie (++) jej, a więc x ++.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.