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.