数组中的幻数? - C ++

时间:2010-01-18 21:43:39

标签: c++ magic-numbers

我是一个相当新的程序员,如果这些信息很容易获得,我很抱歉,我还没有找到它。

这是我的问题:

当您使用文字编号访问数组的特定元素时,是否会被视为幻数?

例如:

arrayOfNumbers[6] // Is six a magic number in this case?

我问这个问题,因为我的一位教授坚持认为程序中的所有字面数字都是魔数。我只是使用实数来访问数组的元素,而不是为每个元素使用命名常量。

谢谢!

11 个答案:

答案 0 :(得分:22)

这实际上取决于背景。如果你有这样的代码:

arr[0] = "Long";
arr[1] = "sentence";
arr[2] = "as";
arr[3] = "array.";

...然后0..3不被视为幻数。但是,如果你有:

int doStuff() 
{
   return my_global_array[6];
}

...然后6绝对是一个神奇的数字。

答案 1 :(得分:6)

这很神奇。

我的意思是,为什么你正在访问第6个元素?什么是应该应用于该数字的语义?我们所知道的就是“第6个(从零开始)数字”。如果我们知道arrayOfNumbers的声明,我们会进一步了解其类型(例如intdouble)。

但如果你说:

arrayOfNumbers[kDistanceToSaturn]; 

...现在它对于阅读代码的人来说意义更大。

通常,一个迭代遍历一个数组,对每个元素执行一些操作,因为一个人不知道该数组有多长,你不能以硬编码的方式访问它。

然而,有时数组元素具有特定含义,例如,在图形编程中。有时,数组总是大小相同,因为数据需要它(例如某些变换矩阵)。在这些情况下,通过数字访问特定元素可能会也可能不会:领域专家会知道你在做什么,但是通才可能不会。给魔术索引编号一个名称会使那些必须维护代码的人更明显,并帮助你防止意外输入错误的代码。

在我上面的例子中,我假设你的阵列保持从太阳到行星的距离。太阳将是第0个元素,因此arrayOfNumbers [kDistanceToSun] = 0.然后当你递增时,每个元素包含到下一个最远行星的距离:水银,金星等。这比只输入数字更可读。你想要的星球。在这种情况下,阵列具有固定的大小,因为有固定数量的行星(嗯,除了整个冥王星的崩溃)。

另一个问题是“arrayOfNumbers”没有告诉我们数组的内容。我们已经知道了它的一系列数字,因为我们在你所说的int arrayOfNumers[12345];或者你声明它的地方看到了声明。相反,像:

int distanceToPlanetsFromSol[kNumberOfPlanets];

...让我们更好地了解数据实际是什么以及它的语义是什么。作为程序员,您的目标之一应该是编写以这种方式自我记录的代码。

然后我们可以在其他地方争论kNumberOfPlanets应该是8还是9. :)

答案 2 :(得分:5)

您应该问问自己为什么要访问该特定职位。在这种情况下,我假设如果你正在做arrayOfNumbers[6],第六个位置有一些特殊含义。如果你认为这意味着什么,你可能会意识到隐藏它是一个神奇的数字。

答案 3 :(得分:2)

另一种看待它的方式:

如果程序有可能需要访问第7个元素而不是第6个元素,该怎么办?你或你的维护者会知道吗?例如,如果第6个条目是CA中树的数量,则放置

是一件好事
 #define CA_STATE_ENTRY 6

然后,如果现在表重新排序,有人可以看到他们需要将其更改为9(比方说)。顺便说一下,我并不是说这是维护状态数组的最佳方法 - 它可能不是。

同样,如果以后的人想要改变程序来处理俄勒冈州的树木,那么他们就知道要更换

 trees[CA_STATE_ENTRY]

 trees[OR_STATE_ENTRY]

重点是

 trees[6]

不是自我记录

当然对于c ++来说,它应该是一个枚举而不是#define

答案 4 :(得分:1)

您必须为有意义的答案提供更多背景信息。并非所有的字面数字都是神奇的,但很多都是。在这样的情况下,根本没有办法确定,尽管大多数情况下我可以想到一个明确的数组索引>> 1可能有资格作为魔法。

答案 5 :(得分:1)

一个程序中的所有文字都不符合“魔术数字”的标准 - 但这个肯定似乎是。 6没有告诉我们为什么要访问数组的特定元素。

是一个神奇的数字,即使在第一次检查(或至少是最低限度的检查)为什么要使用该值时,您的意义也要非常清楚。例如,很多代码都会执行以下操作:&x[0]。在这种情况下,通常非常清楚'0'实际上只是意味着“数组的开头。”

答案 6 :(得分:0)

如果你需要访问数组的特定元素,那么你可能做错了。

你应该几乎总是迭代整个数组。

答案 7 :(得分:0)

如果你的程序正在做一些特别涉及6号的特殊事情,那么这只是一个神奇的数字。你能提供一些背景吗?

答案 8 :(得分:0)

这是教授的问题,他们往往太学术化了。从理论上讲,他是正常的,但通常情况下,当数字嵌入在 data 流中时,通常会在更严格的上下文中使用幻数,从而允许您检测流的某些属性(如签名标题)例如,文件类型)。 另请参阅this Wikipedia entry

答案 9 :(得分:0)

通常不是软件中的所有常量值都称为幻数。 java类文件始终以十六进制值0xcafebabe以windows .exe开头 文件与MZ 0x4d,0x5a,这可以让你快速(但不是肯定)识别 二进制文件的内容。

答案 10 :(得分:0)

在符合MISRA标准的系统中,除0和1之外的所有值都被视为幻数。我的观点一直是,如果恒定值是显而易见的,或者可能不会改变,那么将其留作数字。如果有疑问,可以创建一个独特的常数,因为长期维护会更容易。