| 運算子 | 名稱 | 運算值 (表達式結果) | 副作用 (變數最終值) |
|---|---|---|---|
++i | 前置遞增 | 遞增後的值 | i = i + 1 |
i++ | 後置遞增 | 遞增前的值 | i = i + 1 |
共同點:最終 `i` 都會加 1。
不同點:表達式本身的值不同。
#include
int main(void) {
int i = 3, j = 3;
int k = i++; // 後置遞增
int m = ++j; // 前置遞增
printf("i = %d, j = %d\n", i, j); // i=4, j=4 (最終值相同)
printf("k = %d, m = %d\n", k, m); // k=3, m=4 (運算值不同!)
return 0;
}
++i:**先加,後用** —— 符號在前,動作在前。i++:**先用,後加** —— 符號在後,動作在後。i++; // 效果同 ++i;
++i;
編譯器生成相同機器碼,無效能差異。
int a = 5;
printf("%d %d %d\n", a, ++a, a++); // 未定義行為!參數求值順序不規定
鐵律:單一表達式中同一變數只能修改一次,否則 UB。
int i = 0;
while (i++ < 5) { ... } // 執行 5 次:0,1,2,3,4 (比較用舊值)
int j = 0;
while (++j < 5) { ... } // 執行 4 次:1,2,3,4 (比較用新值)
int arr[10] = {0};
int idx = 0;
arr[idx++] = 10; // 存入 arr[0],idx 變 1
arr[++idx] = 20; // idx 先變 2,存入 arr[2]
; ++i (x86-64)
inc DWORD PTR [rbp-4] ; 直接在記憶體遞增
mov eax, DWORD PTR [rbp-4] ; 載入新值作為表達式結果
; i++ (x86-64)
mov eax, DWORD PTR [rbp-4] ; 載入舊值作為表達式結果
inc DWORD PTR [rbp-4] ; 記憶體遞增
現代編譯器優化後,單獨使用時指令數相同;嵌入複雜表達式時,++i 避免暫存舊值,**理論上略快**。
++i (C++ 迭代器慣例,C 語言無差異)。邏輯完全對稱,--i 回傳遞減後值,i-- 回傳遞減前值。
++i 與 i++ 的**副作用相同**,**運算值不同**。牢記「符號位置 = 動作時機」,並在複合表達式中**避免多重副作用**,即可寫出正確、可維護的代碼。