首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C 語言前置遞增與後置遞增 (++i vs i++) 深度解析

     編輯:關於C語言

核心差異一覽表

運算子名稱運算值 (表達式結果)副作用 (變數最終值)
++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++:**先用,後加** —— 符號在後,動作在後。

實務場景差異

1. 獨立陳述句:完全等價

i++;  // 效果同 ++i;
++i;

編譯器生成相同機器碼,無效能差異。

2. 函數參數/複合表達式:極大差異

int a = 5;
printf("%d %d %d\n", a, ++a, a++);  // 未定義行為!參數求值順序不規定

鐵律:單一表達式中同一變數只能修改一次,否則 UB。

3. 迴圈條件判斷

int i = 0;
while (i++ < 5) { ... }   // 執行 5 次:0,1,2,3,4 (比較用舊值)
int j = 0;
while (++j < 5) { ... }   // 執行 4 次:1,2,3,4 (比較用新值)

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 避免暫存舊值,**理論上略快**。

最佳實踐建議

  1. 獨立行:習慣用 ++i (C++ 迭代器慣例,C 語言無差異)。
  2. 表達式中:嚴禁 在同一表達式對同一變數同時使用 `++`/`--` 多次。
  3. 迴圈索引:`for (int i = 0; i < n; ++i)` 慣用前置遞增。
  4. 需要舊值:明確拆分兩行 `val = i; i++;` 可讀性最高。

延伸:前置/後置遞減 (--i vs i--)

邏輯完全對稱,--i 回傳遞減後值,i-- 回傳遞減前值。

結語

++i 與 i++ 的**副作用相同**,**運算值不同**。牢記「符號位置 = 動作時機」,並在複合表達式中**避免多重副作用**,即可寫出正確、可維護的代碼。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved