魔術數字 (程式設計)
此條目没有列出任何参考或来源。 (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
)这两种字符串。