魔术数字 (程序设计)

✍ dations ◷ 2025-11-22 23:09:07 #计算机编程,反模式

程序设计中所谓的魔术数字(magic number)可能有以下含意:

魔术数字可以是指硬编码在代码里的具体数值(如“10”“123”等以数字直接写出的值)。虽然程序作者写的时候自己能了解数值的意义,但对其他程序员而言,甚至制作者本人经过一段时间后,会难以了解这个数值的用途,只能苦笑讽刺“这个数值的意义虽然不懂,不过至少程序能够运行,真是个魔术般的数字”而得名(起源参考平方根倒数速算法)。

因为下述理由,一般认为代码中不应该含有魔术数字。

例1:

price_tax = 1.05 * price

例1是对输入的价格(price)计算含税(price_tax)售价的程序。但税率并不是万年不变,当政府调整税率时,会有修改程序的必要。这里“1.05”就是一种魔术数字,“为什么是1.05”会让人无法马上了解。下面是去掉魔术数字的示例,程序容易了解也容易修正。

例1 (修正):

TAX = 0.05price_tax = (1.0 + TAX) * price

例2:

setColor("text", 0xffffff)

例2是设置以白色显示代码。然而十六进制的色码0xffffff很难直觉看懂是“白色”,故也算是一种魔术数字。下面是一种拿掉魔术数字的方式。

例2 (修正):

white = 0xffffffsetColor("text", white)

像这样,将魔术数字置换成常量或枚举类型是经常用来解决魔术数字问题的手段。由于常量可以赋予易懂的名称,可使帮助阅读者了解数值的意义。当然,在程序初始化部分定义的常量列表不称为魔术数字。

例3:

year = (new Date()).getYear() - 1911;

例3是用来获取今年之民国纪年的代码。然而将“1911”硬编码在代码里并不尽理想,例如程序不易在其他国家使用等。下面是一种拿掉魔术数字的方式。

function getMinguoYear() { return (new Date()).getYear() - 1911; }year = getMinguoYear();

这个示例则使用函数来包装整段计算民国纪年的逻辑,函数内则直接保留数值1911。这样做的好处是在程序中可借由getMinguoYear()这个函数名称更容易了解程序意图,并对未来若需支持其他国家时保留弹性。例如,需要使用日本历时,可只抽换函数部分而不动到程序所有参考年份运算的地方。

另外,在 一些编程语言中,1与0经常直接作为“真”、“假”的意义(布尔值)使用,有时候也不被认为是魔术数字。(但近年的语言多半建议使用与替代。)

魔术数字也会在文件中使用。在特定文件格式中加入固定数值和固定字符串,然后便可以通过检查文件是否包含这些数据来快速地识别文件格式。

例如:GIF文件开头会包含GIF89a47 49 46 38 39 61)或GIF87a47 49 46 38 37 61)这两种字符串。

相关

  • 语言美国最广泛的语言是英语,但美国联邦政府并没有设有官方语言。历史上存在过很多语言。其他有美国本土的语言,也有来自欧洲、亚洲等地区的语言。目前美国所使用的语言约有430种,
  • 睡眠不足睡眠剥夺(英语:sleep deprivation),又称作睡眠不足(英语:insufficient sleep)可以是长期的,也可以是短期的。长期的睡眠不足可能会导致疲劳、白天昏昏欲睡、反应迟钝、体重增加或减
  • 杉田玄白杉田 玄白(日语:すぎた げんぱく,1733年10月20日-1817年6月1日)名翼(たすく)、字子凤、号鷧、晩年号九幸翁。,日本江戸时代的兰学医生,主办医学私塾天真楼,曾翻译《解体新书》。 杉田
  • 飞机摄影飞机摄影,是指通过摄影的方式记录有动力固定翼飞行器、旋翼机、滑翔机、热气球、飞艇、滑翔翼以及机场的一种活动,具有这种爱好或从事这种行为的人,则是“飞机摄影爱好者”。飞
  • 绍武绍武是南明绍武帝的年号,隆武二年(1646年)十一月绍武帝称帝后,预定于明年丁亥年(猪年,1647年)改元,十二月绍武政权覆亡,该年号实际并未使用。洪武 → 建文 → 永乐 → 洪熙 → 宣德
  • 新竹科学园区坐标:24°46′56″N 121°00′23″E / 24.7823005°N 121.0062859°E / 24.7823005; 121.0062859新竹科学园区(简称竹科),原名新竹科学工业园区,是台湾的第一座科学园区,涵盖范围
  • 奉化芋艿头奉化芋艿头为中国浙江省宁波市奉化区出产的芋艿品种,原产于萧王庙,溪口、尚田等地也有种植:1237。20世纪30年代,奉化芋艿头曾经行销宁波、上海,宁波地区有俗语“走过三关六码头,
  • 1962年乞讨(禁止)法《1962年乞讨(禁止)法》(英语:Begging (Prohibition) Act, 1962)是尼泊尔议会于1962年4月11日通过的一项法案,于2018年正式生效。该法禁止人民乞讨或鼓励未满16岁的儿童向他人行乞
  • 达乌德 (人名)达乌德(阿拉伯语:داوود‎)是一个阿拉伯语名字或姓氏。它是穆斯林的常用名字。在中国穆斯林人名中常被译为“达吾德”,在马来西亚常被译为“道勿”,另有达伍德、达武德、多德
  • 天主教普罗维登斯教区天主教普罗维登斯教区(拉丁语:Diocesis Providentiensis、英语:Roman Catholic Diocese of Providence)是美国一个罗马天主教教区,属哈特福德总教区。成立于1872年2月16日。范围