魔术数字 (程序设计)

✍ dations ◷ 2025-11-24 15:38:03 #计算机编程,反模式

程序设计中所谓的魔术数字(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)这两种字符串。

相关

  • 母公司控股公司(英语:Holding company),或称握股公司、控制公司(Controlling company)、母公司(Parent company),为以拥有其他公司多数控制股权的方式,掌握其管理及营运的公司。一般而言,控股
  • 弗兰克·惠特尔弗兰克·惠特尔爵士(英语:Sir Frank Whittle,1907年6月1日-1996年8月9日),英国皇家空军军官, 航空发动机工程师,与德国人汉斯·冯·奥海恩分别独立设计了喷射发动机。1907年,惠特尔出
  • 论出版自由论出版自由(英语:Areopagitica: A speech of Mr. John Milton for the liberty of unlicensed printing to the Parliament of England),是1644年约翰·弥尔顿出版的一本反对审
  • 杜兰尼王朝杜兰尼王朝(普什图语:د درانیانو واکمني‎),又称阿富汗帝国,是一个普什图族王朝,领土面积包括了今日的阿富汗、伊朗东北部、巴基斯坦以及印度旁遮普地区。杜兰尼王
  • 饿狼传说饿狼传说(日语:餓狼伝説,英语:Fatal Fury)是1991年SNK发售的一款2D对战格斗游戏,以及此后的同系列对战格斗游戏,系列主角为泰利·波格。其同于SNK的拳皇系列中以队伍参赛的KOF格斗
  • 保导联盟事件保导联盟事件(보도연맹 사건)是指韩战初期,大韩民国国军在韩国针对共产党支持者进行的一场大规模屠杀。其中大部分死者为与共产党关系甚浅、甚至不相干的人士。1949年,韩国政府
  • 海相沉积海相沉积是沉积相的一个一级相组。受海水物理化学条件、水动力状况、海底地形与海水深度等因素影响,海相沉积又可分为滨岸相、浅海陆棚相、半深海相、深海相等多个二级相组,各
  • 童受童受论师(梵语:Kumāralabdha,生卒年不详),音译为拘摩罗逻多、鸠摩罗罗陀、鸠摩罗驮、究摩罗陀、鸠摩罗多,意译作童受、童首、豪童、童子。印度部派佛教著名论师,出自说一切有部,与
  • 巴克·鲁克斯顿巴克·鲁克斯顿(1899年3月21日-1936年5月12日)是一名出生于印度的英国医生,因1935年9月在英格兰兰开斯特的家中谋杀他的同居妻子伊莎贝拉·鲁克斯顿(原名克尔)和家庭女佣玛丽·简
  • 心灵捕手是一部由葛斯·范桑于1997年导演的电影,故事发生地是麻省的波士顿,主要在多伦多取景拍摄。故事围绕在年轻人威尔·杭汀(Will Hunting),一个在麻省理工学院担任清洁工,却在高等数学