iT邦幫忙

2026 iThome 鐵人賽

DAY 7
0
自我挑戰組

韌體工程師的不只 0x10 個問題系列 第 7

Day 7 - 神奇的「最大匹配原則」與前後置遞增

  • 分享至 

  • xImage
  •  

試分析以下程式碼,並推估其運算結果:

int a = 5, b = 7, c;
c = a+++b;

等等,這 a+++b 是什麼東西?不會報錯嗎?

最大匹配原則 Maximal Munch

當編譯器遇到一連串符號時,會從左到右依序吃進最多字元,組成合法的運算子,所以當編譯器面對 a+++b,會這樣做:

  1. 看到變數 a
  2. 看到第一個 +,變成 a+,這時還不是合法運算子。
  3. 再看到第二個 +,變成 a++,是一個合法運算子。
  4. 接著看到第三個 +,詮釋成 (a++)+,先處理完合法的 a++,再把第三個 + 視為獨立的運算子。
  5. 把變數 b 也考慮進去。

因此最後變成:

c = (a++) + b;

那這樣結果是多少呢?讓我們直接執行以下的完整 C++ 程式碼看看:

#include <iostream>

int main()
{
    int a = 5, b = 7, c;
    c = a+++b;

    std::cout << "a = " << a << std::endl;
    std::cout << "b = " << b << std::endl;
    std::cout << "c = " << c << std::endl;

    return 0;
}

執行結果如下:

a = 6
b = 7
c = 12

等等,既然 a++ 已經把 a6 變成 7,那再加上 7 之後,c 不是應該等於 13 嗎?

「前置遞增」與「後置遞增」

這關鍵就在於 ++ 寫的位置,寫在 a 後面代表「後置遞增(post-increment)」,也就是雖然變數有遞增,但卻是拿舊值去運算,流程可以想成:

  1. int temp = a;:先把 a 的舊值複製一份。
  2. a = a + 1;a 馬上變成 6
  3. c = temp + b;:把剛剛複製的舊值加上 b

所以 c 是舊值 5 加上 b 的結果。

如果想要 a 用已經加上 1 的結果去運算呢?那就得用「前置遞增(pre-increment)」,寫法為 ++a

比較

前置遞增 後置遞增
寫法 ++a a++
意義 a 先加 1,再回傳加 1 「後」的結果 a 先回傳加 1 「前」的結果,再加 1

因此,原本的範例如果寫成 c = ++a+b;,就可以依序完成:

  1. ++a:把 a 先加 1,並回傳加上 1 之後的結果 6
  2. +b:把剛剛算出來的 6 加上 b,而 b7,因此 6 + 7 = 13
  3. 將算出來的 13 賦值於 c,因此 c = 13

參考資料

  1. 韌體工程師的0x10個問題

上一篇
Day 6 - 不能改變值的 const 跟 literal
下一篇
Day 8 - 隱含類型轉換的陷阱
系列文
韌體工程師的不只 0x10 個問題22
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言