魔术数字 (程序设计)

✍ dations ◷ 2025-11-25 11:37:15 #计算机编程,反模式

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

相关

  • 吐根碱吐根碱是一种抗原虫药和呕吐诱导药物,它提取自吐根树,并以其催吐药性而命名。最早对吐根碱的应用是口服提取自吐根或吐根树根的萃取物,这种萃取物中原本以为只包含了一种生物碱
  • 词干在语言学中,词干(stem),或语干,是词的一部分。在不同情况下使用,其含义有差异。词干的其中一种含义,是指词缀所附着的部分。 例如在英语单词friendships中包含了词干friend,词缀-shi
  • 西格列汀西格列汀(英语:Sitagliptin),商品名为佳糖维,是一种口服降糖药(抗糖尿病药),属于二肽基肽酶-4(DPP-4)抑制剂,由默克公司研发和销售。西格列汀可以单独应用也可以与其他口服降糖药组成复
  • 澳大利亚旗帜列表这里是澳大利亚联邦相关旗帜的旗帜列表。民用旗政府旗军用旗民船旗政府船旗军舰旗
  • 俄罗斯联邦区域发展部俄罗斯联邦区域发展部(俄语:Министерство регионального развития Российской Федерации – Минрегион Ро
  • 希里黛玉希里黛玉(泰米尔语:ஸ்ரீதேவி,英语:Sridevi;婚后全名叫希里黛玉·卡浦尔(Sridevi Kapoor),1963年8月13日-2018年2月24日),印度女演员,活跃于二十世纪末期。身为著名的印度国宝级
  • 皮埃尔·勒隆皮埃尔·勒隆(法语:Pierre Lelong,1912年3月14日-2011年10月12日),法国数学家,提出了庞加莱-勒隆方程。
  • 课征金融交易税以协助公民组织课征金融交易税以协助公民组织(法文:Association pour la taxation des transactions pour l'aide aux citoyens,缩写:ATTAC,为英文与法文中的“进攻”谐音)是一个提倡课征外汇交
  • 应用网络架构应用网络架构 (英文: App Network Architecture)是为设计、构建和管理一个应用网络提供一个构架和技术基础的蓝图。应用网络架构定义了网络中各个应用直接的逻辑或者拓扑关
  • 可重入若一个程序或子程序可以“在任意时刻被中断然后操作系统调度执行另外一段代码,这段代码又调用了该子程序不会出错”,则称其为可重入(reentrant或re-entrant)的。即当该子程序正