魔術數字 (程式設計)
此條目沒有列出任何參考或來源。 (2014年3月12日) |
在程式設計中,魔術數字(magic number)可能指:
- 缺乏解釋或命名的獨特數值。常常在程式中出現多次,並且可以(從規範上而言也應當)被有名字的常數取代。
- 用於辨識一個檔案格式或協定類型的一段常數或字串,例如UNIX的特徵簽章。
- 不易於其他值混淆的值,例如UUID。
未命名的具體數值
魔術數字可以是指寫死在程式碼裏的具體數值(如「10」「123」等以數字直接寫出的值)。例如,在下面這個計算含稅價格的程式片段中,1.05
即是一個典型的魔術數字:
price_tax = 1.05 * price
雖然程式作者寫的時候自己能了解數值的意義,但對其他程式員而言,甚至製作者本人經過一段時間後,會難以了解這個數值的用途,只能苦笑諷刺「這個數值的意義雖然不懂,不過至少程式能夠執行,真是個魔術般的數字」而得名(起源參考平方根倒數速演算法)。
魔術數字帶來的常見的負面影響包括:
- 數值的意義難以了解,影響可讀性。
- 數值需要變動時,可能要改不只一個地方。
- 當魔術數字是浮點數時,若在不同地方使用精度不同的數值,可能產生難以溯源的誤差問題。例如在程式中某處圓周率使用
3.14159
,另一處又使用3.1415926
。
因此,一般認為應該用一個帶有有意義名稱的常數取代魔術數字,例如上述的例子可以改為:
TAX = 0.05 price_tax = (1.0 + TAX) * price
在電腦中以數字表示的其他資訊也可能成為魔術數字,例如以十六進制數字表示的RGB格式的顏色:
setColor("text", 0xffffff)
當讀到這段代碼時,很難第一時間就看懂0xffffff
代表白色。如果使用名稱清晰的常數,則可以使程式更清晰:
WHITE = 0xffffff setColor("text", WHITE)
魔術數字也可以指其他非數字的值,例如字元,字串等等。
但是,並非所有未命名的具體數值都是魔術數字。一般而言,只要數字能讓人一眼明白其含義,並且基本沒有需要改變的可能,就不會被認為是魔術數字。常見的例子包括:
- 迴圈的初始值和步進值,如
for (int i = 0; i < max; i += 1)
中的0
和1
。 - 數學公式中的簡單常數,例如一元二次方程判別式公式
d = b * b - 4 * a * c
中的4
。
在檔案中
魔術數字也會在檔案中使用。在特定檔案格式中加入固定數值和固定字串,然後便可以通過檢查檔案是否包含這些數據來快速地辨識檔案格式。
例如:GIF檔案開頭會包含GIF89a
(47
49
46
38
39
61
)或GIF87a
(47
49
46
38
37
61
)這兩種字串。