2.9 未定義行為(Undefined Behavior, UB)
¶什麼是未定義行為?
有些寫法,C++ 並沒有規定「會發生什麼事」——這種就叫未定義行為(UB)。一旦程式踩到 UB,結果就沒人能保證:可能印出莫名其妙的值、可能直接當掉(崩潰),也可能在你的電腦上看起來正常、換一台電腦或換個編譯器就出錯。所以我們要學會避開它。
以下是幾種新手常踩的 UB:
¶1. 使用未初始化的局部變數
#include <iostream>
using namespace std;
int main() {
int x; // ✗ 未初始化
cout << x << endl; // UB:印出垃圾值
return 0;
}
解決方法: 宣告時初始化
int x = 0; // ✓ 初始化為 0
¶2. 除以零
#include <iostream>
using namespace std;
int main() {
int a = 10, b = 0;
cout << a / b << endl; // ✗ UB:除以零
return 0;
}
結果: 在某些系統上會崩潰,或輸出不可預測的值
解決方法: 做除法前,先確認除數不是 0(下面的 if 條件判斷第三單元才會教,這裡先看懂「除數是 0 就別做除法」的意思即可)
if (b != 0) {
cout << a / b << endl; // ✓
}
¶3. 整數溢位
#include <iostream>
#include <climits>
using namespace std;
int main() {
int x = INT_MAX; // int 的最大值:2,147,483,647
x = x + 1; // ✗ 溢位:超過 int 能表示的範圍
cout << x << endl; // 在常見環境會「環繞」成最小值 -2147483648
return 0;
}
整數溢位嚴格說也是 UB,但和上面兩種不太一樣:在競賽常用的環境裡,你常常會看到它固定地「環繞」(不像未初始化變數那樣每次都不同)。不過這不是 C++ 保證的規則——看到溢位,就把它當成程式出錯了。下一小節 2.10 會仔細講;總之該避免還是要避免,因為環繞後的值幾乎一定不是你要的答案。