PHPの++ $ iと$ i ++の違いは何ですか?


回答:


96

++$iはプリインクリメントであり、$i++ポストインクリメントです。

  • pre-increment:インクリメント変数 i最初にから、参照を解除します。
  • ポストインクリメント:参照を解除してからインクリメント i

「PHPではポストインクリメント($ i ++)とプリインクリメント(++ $ i)が可能であるという事実を利用してください。ただし、$ j = $ i ++のようなものを記述していない限り、意味は同じです。プレインクリメントはほぼ10%高速です。つまり、機会があれば、特にタイトなループで、特にマイクロ最適化に精通している場合は、ポストインクリメントからプレインクリメントに切り替える必要があります。」- TuxRadar

さらに明確にするために、PHPでのポストインクリメントは、この10%のオーバーヘッドとプレインクリメントに起因する一時変数を格納するものとして文書化されています。


6
これは一般的な経験則ですか、それともPHP固有ですか。
ゾイドバーグ

1
...ソースは私の答えに記載されています。私自身からそれをチェックしていない...私はかかわらず、PHPのソースコードを見て、私ができると思います...
jldupont

3
私自身は他の言語に一般化するつもりはありません。
jldupont 2009年

3
ポストインクリメントは一時変数を作成し、オーバーヘッドを作成するため、プレインクリメントの速度の増加はPHP固有です。
Corey Ballou

4
@knittlそれは(1つの希望)非常に迅速な操作の10%であることを忘れないでください:)
jensgram 2009年

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は一時変数を必要とするのでしょうか?なぜですか:$ a = $ i; $ i = $ i + 1;
テイラーヴァンス

@テイラー、それは素晴らしい質問です!$ iを次のような関数呼び出しに置き換えてみてください。$a=func()++++なしで、func()を複数回呼び出さずに$ iを書き直す方法を自問してください。
ShalomCraimer20年

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 2015年

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

簡単な例をありがとう。今、私は分かる。
プラディサ2018年

7

違いは次のとおりです。変数++$iをインクリメントして$i更新された値$i++を返しますが、元の値を返すので、インクリメントします。

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

5

jldupontのポイントを説明するには:

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

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の元の値を$ jに割り当てた後でのみ、$ iの値をインクリメントします。

++ $ iはプリインクリメントとして知られています。値を$ jに割り当てる前に、$ iの値をインクリメントするため、更新された$ 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. 変数$ somethingは、$ iでインデックス付けされた配列要素に割り当てられます
  2. 変数$ iがインクリメントされます
  3. 反復は終了し、状態がチェックされます

それ以外の場合はすべて、プレフィックス演算子を使用する必要があります。これにより、コードがはるかに明確になります(特定の変数の増分値を既に使用していることは確かです)。


接尾辞が厳密に必要でない限り、接頭辞の使用を推奨することに賛成。
developerbmw

0

次のコードを実行して、++ $ iが$ i ++よりも10%速いかどうかをテストしました。確かに、コードの結果は安定していませんが、それでも少なくとも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ずつ増加します。2つの違いは、戻り値にあります。

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

このルールを覚えておくために、2つの構文について考えます。プレフィックス増分を入力すると、++ xと表示されます。ここでは++の位置が重要です。++ xとは、最初に(++)をインクリメントしてから、xの値を返すことを意味します。したがって、++ xになります。接尾辞の増分は逆に機能します。x ++とは、最初にxの値を返し、その後にインクリメント(++)することを意味します。つまり、x ++です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.