当人们谈论在计算机编程中使用“魔术数字”时,他们的意思是什么?
答案 0 :(得分:38)
魔术数字是代码中的任何数字,对于知之甚少的人来说并不是很明显。
例如,以下代码:
sz = sz + 729;
中有一个神奇的数字,写得更好:
sz = sz + CAPACITY_INCREMENT;
一些极端的观点表明你的代码中除了-1,0和1之外你不应该有任何数字,但我更喜欢一种不那么教条的观点,因为我会立刻认出24,1440,86400,3.1415,2.71828和1.414 - 它一切都取决于你的知识。
然而,即使我知道一天有1440分钟,我可能仍然使用MINS_PER_DAY
标识符,因为它会搜索它们更容易。谁说上面提到的容量增量也不会是1440而你最终改变了错误的值?对于低数字尤其如此:双重使用37197的机会相对较低,将5用于多个事物的几率非常高。
使用标识符意味着您不必浏览所有700个源文件,并在容量增量更改时将729
更改为730
。你可以改变一行:
#define CAPACITY_INCREMENT 729
为:
#define CAPACITY_INCREMENT 730
并重新编译该批次。
将这与魔术常数进行对比,这是因为天真的人认为只是因为他们从代码中删除了实际的数字,他们可以改变:
x = x + 4;
为:
#define FOUR 4
x = x + FOUR;
这会为您的代码添加绝对零的额外信息,这完全是浪费时间。
答案 1 :(得分:6)
“幻数”是出现在
等语句中的数字if days == 365
假设你不知道一年中有365天,你会发现这句话毫无意义。因此,将所有“魔术”数字(在程序中具有某种重要性的数字)分配给常量是一种很好的做法,
DAYS_IN_A_YEAR = 365
从那以后,与之相比。它更容易阅读,如果地球被排除在外,并且我们获得了额外的一天......你可以轻松地改变它(其他数字可能更有可能改变)。
答案 2 :(得分:5)
有多个含义。大多数答案已经给出的(一个任意未命名的数字)是一个非常普遍的答案,我唯一要说的就是有些人走向定义的极端......
#define ZERO 0
#define ONE 1
如果你这样做,我会追捕你,毫不留情。
但是,另一种幻数用于文件格式。它只是一个值,通常是文件中的第一件事,它有助于识别文件格式,文件格式的版本和/或特定文件的字节序。
例如,您可能有一个幻数0x12345678。如果你看到这个神奇的数字,那么你可以看到一个正确格式的文件。另一方面,如果您看到0x78563412,那么您可能会看到相同文件格式的字节序交换版本。
“魔术数字”这个术语有点被滥用,但几乎所有标识文件格式的东西都被滥用 - 包括标题中相当长的ASCII字符串。
答案 3 :(得分:4)
维基百科是您的朋友(Magic Number文章)
答案 4 :(得分:3)
到目前为止,大多数答案都将幻数描述为一个非自我描述的常数。作为一个“老派”程序员自己,回到那一天我们将魔术数字描述为任何常量,这些常量被分配了一些影响代码行为的特殊目的。例如,数字999999或MAX_INT或其他完全任意的。
魔术数字的一个大问题是它们的目的很容易被遗忘,或者在另一个完全合理的语境中使用它的价值。
作为一个粗暴而极其人为的例子:
while (int i != 99999)
{
DoSomeCleverCalculationBasedOnTheValueOf(i);
if (escapeConditionReached)
{
i = 99999;
}
}
使用或不命名常量的事实并不是真正的问题。在我可怕的例子中,值会影响行为,但是如果我们需要在循环时更改“i”的值呢?
显然,在上面的例子中,你不需要一个幻数来退出循环。你可以用break语句替换它,这是魔术数字的真正问题,它们是一种懒惰的编码方法,并且总是可以被不太容易失败的东西所取代,或者随着时间的推移失去意义。
答案 5 :(得分:2)
除了应用程序本身之外,任何对任何人都没有明显意义的东西。
if (foo == 3) {
// do something
} else if (foo == 4) {
// delete all users
}
答案 6 :(得分:2)
幻数是某些变量的特殊值,会导致程序以特殊方式运行。
例如,通信库可能会采用Timeout参数,并且可以定义幻数“-1”以指示无限超时。
答案 7 :(得分:1)
术语幻数通常用于描述代码中的某些数字常量。出现的数字没有任何进一步的描述,因此其含义是深奥的。
使用命名常量可以避免使用幻数。
答案 8 :(得分:0)
在0或1以外的计算中使用未由某些标识符或变量定义的数字(这不仅可以通过在一个地方更改数字而在几个地方轻松更改,还可以使读者清楚这个数字是多少)。
答案 9 :(得分:0)
简单而真实的单词中,幻数是三位数,前两位的平方和等于第三位。 EX-202, as,2 * 2 + 0 * 0 = 2 * 2。 现在,java中的WAP接受一个整数并打印是否是一个幻数。
答案 10 :(得分:0)
它可能看起来有点平庸,但每种编程语言至少有一个真正的神奇数字。
0
我认为,在几乎所有程序员的魔杖颤抖中统治它们都是神奇的魔杖。
FALSE不可避免地为0 TRUE不是(FALSE),但不一定是1!可以是-1(0xFFFF)
NULL不可避免地为0(指针) 并且大多数编译器允许它,除非他们的类型检查是彻头彻尾的狂热。
0是数组元素的基本索引,除非语言过于陈旧,基本索引为“1”。然后可以方便地编码(i = 0; i< 32; i ++),并期望'i'将从基数(0)开始,并且增加到,并且停止在32-1 ...第32个成员一个数组,或其他什么。
0是许多编程语言字符串的结尾。 “停在这里”的价值 0同样内置于X86指令中以“有效地移动字符串”。节省许多微秒。
程序员经常使用0表示例程执行中“没有出错”。它是“非例外”代码值。可以使用它来表示缺少抛出异常。
零是程序员最经常给出的做一些完全无关紧要的工作量的答案,比如将活动单元格的颜色改为紫色而不是亮粉色。 “零,伙计,就像零!”
0是我们希望实现的程序中的错误计数。 0个未解释的例外,0个未终止的循环,0个无法实际获取的递归路径。 0是我们试图在编程劳动,女朋友(或男朋友)“问题”,糟糕的餐厅体验和一个人的汽车的一般特质方面实现的渐近线。
是的,0确实是一个神奇的数字。远比任何其他价值更具魔力。没什么......唉,接近了。
rlynch@datalyser.com