| 運算符 | 名稱 | 執行順序 | 表達式值 |
++$i | 前置遞增 | **先遞增**,後使用新值 | 遞增**後**的值 |
$i++ | 後置遞增 | **先使用**當前值,後遞增 | 遞增**前**的值 |
等價代碼展開
// ++$i 等價於
$i += 1;
return $i;
// $i++ 等價於
$temp = $i;
$i += 1;
return $temp;
實例演示
$i = 2;
$a = ++$i; // $i=3, $a=3
echo "前置: i=$i, a=$a\n";
$i = 2;
$b = $i++; // $b=2, $i=3
echo "後置: i=$i, b=$b\n";
// 複雜表達式
$i = 1;
echo $i++ + ++$i; // 解析: (1) + (3) = 4
// 步驟: 1) $i++ 取值1, $i變2 2) ++$i 遞增為3, 取值3 3) 1+3=4
for 循環中常見寫法
// 兩種寫法結果相同,因遞增表達式值未被使用
for ($i = 0; $i < 10; $i++) { /* ... */ }
for ($i = 0; $i < 10; ++$i) { /* ... */ }
教程常推薦 ++$i,源於 C++ 迭代器效率習慣,PHP 中差異極微。
效率差異本質
- 後置遞增 需創建臨時變量保存舊值,理論上多一次內存讀寫
- 現代編譯器優化:PHP (Zend Engine)、GCC、LLVM 等在**未使用表達式值**時會將
$i++ 優化為 ++$i
- 實測差異:單次循環納秒級,百萬次循環毫秒級,**可忽略不計**
PHP 內核實現 (Zend VM)
// 簡化版 Zend VM 指令
// POST_INC (後置)
ZEND_VM_HANDLER(ZEND_POST_INC, ...) {
zval *var = GET_OP1_ZVAL_PTR();
ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var); // 複製當前值到結果
increment_function(var); // 遞增
}
// PRE_INC (前置)
ZEND_VM_HANDLER(ZEND_PRE_INC, ...) {
zval *var = GET_OP1_ZVAL_PTR();
increment_function(var); // 先遞增
ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var); // 複製新值到結果
}
可見指令數相同,後置多一次複製舊值操作。
最佳實踐建議
- 獨立語句:
for、while 遞增語句、**習慣用 ++$i** (語義更清晰、無副作用)
- 表達式中使用:避免**在複雜表達式中混用前置/後置**,極易產生難讀、難維護代碼
- 明確語義:需要「用舊值再遞增」用
$i++,需要「先遞增用新值」用 ++$i
- 代碼審查**:發現
$a = $b++ + ++$c 類寫法**強制要求重構**
總結
++$i 與 $i++ 的核心區別在於**表達式求值時刻**:前置返回新值,後置返回舊值。PHP 中性能差異經編譯器優化後幾乎為零。工程實踐中:**獨立語句優先用前置,表達式中避免混用,追求代碼可讀性而非微優化**。
- 上一篇文章: PHP 設計模式實戰:迭代器模式實現與 SPL 標準庫應用
- 下一篇文章: PHP Session 傳遞方式詳解:URL 參數、表單隱藏域、文件存儲三種模式
Copyright ©
程式碼之家 All Rights Reserved