語法書 / AA 競程語法書 上冊 / 第四單元 / i++、++i、i--、--i

4.7 i++、++i、i--、--i

你從 4.3 開始就一直用 i++ 當「把 i 加 1」——那是它最單純的用法。這一節把它完整的故事講清楚:這些運算子單獨使用時就只是加 1 或減 1,但一旦放進運算式、把結果拿去用,前置(++i)和後置(i++)就會有差別——這也是初學最容易搞混的地方。

單獨使用時(i++、++i 都一樣):

  • i++ 相當於 i += 1
  • ++i 也相當於 i += 1
  • i----i 則相當於 i -= 1

在運算式中使用時(有區別):

  • ++i(前置遞增):先加 1,再傳回新的值
  • i++(後置遞增):先傳回舊的值,再加 1
  • --ii-- 類似

範例程式碼

範例:前置 vs 後置(在運算式中)

#include<iostream>
using namespace std;
int main() {
    int x = 5;
    int y = ++x;        // 先讓 x = 6,再把 6 指派給 y
    cout << x << " " << y << "\n";  // 輸出:6 6

    int a = 5;
    int b = a++;        // 先把 5 指派給 b,再讓 a = 6
    cout << a << " " << b << "\n";  // 輸出:6 5

    return 0;
}

執行結果:

6 6
6 5

拆成兩步看y = ++xb = a++xa 都從 5 開始):

寫法 第一步 第二步 結果
y = ++x(前置) 先把 x 加 1 → x = 6 再把新值 6 給 y x = 6, y = 6
b = a++(後置) 先把舊值 5 給 b 再把 a 加 1 → a = 6 a = 6, b = 5

一句話記住:前置是「先加再用」,後置是「先用再加」。

應用:while (n--) 與 while (--n)

「先用再加/減」不是只有考試會考——把後置遞減放進 while 的條件,就是競程裡「重複 n 次」的慣用寫法(4.8 讀入 T 組測資會馬上用到):

int n;
cin >> n;
while (n--) {          // 恰好跑 n 圈
    cout << "Hello\n";
}

回想 4.2 說過:條件放整數時,非 0 當作真、0 當作假。所以 while (n--) 的意思是:先拿 n 目前的值當條件判斷,判斷完再把 n 減 1——正是後置的「先用再減」。以 n = 3 一圈一圈走:

判斷用的值 真假 判斷完 n 變成 動作
3 2 跑第 1 圈
2 1 跑第 2 圈
1 0 跑第 3 圈
0 −1 離開迴圈

恰好 3 圈。兩個細節值得注意:進到迴圈體時 n 已經先減過了(第 1 圈裡 n 是 2,剛好等於「還剩幾圈」);離開迴圈後 n−1,不是 0。

那換成 while (--n) 呢? 前置是「先減再用」:先把 n 減 1,再拿新值當條件。同樣 n = 3:減成 2(真)→ 跑第 1 圈、減成 1(真)→ 跑第 2 圈、減成 0(假)→ 停——只跑 2 圈,永遠比 while (n--) 少一圈。

動手試試看

  1. 先不要執行,自己推印出什麼,再跑一次對答案:
    int a = 3;
    cout << a++ << " " << a << "\n";   // 這兩個各印出多少?
    
  2. 一步一步推:以下 abc 最後各是多少?
    int a = 3;
    int b = ++a;      // a、b?
    int c = a++;      // 接著 a、c?
    cout << a << " " << b << " " << c << "\n";
    
  3. 回顧本節的 danger,說說為什麼 int y = i++ + ++i; 這種寫法不該出現。
  4. 把本節「應用」段的 while (n--) 改成 while (--n),分別輸入 310,先預測各印幾行 Hello 再實際執行對答案(跑 0 之前,先想好怎麼強制停止程式)。