我是一个相当新的程序员,如果这些信息很容易获得,我很抱歉,我还没有找到它。
这是我的问题:
当您使用文字编号访问数组的特定元素时,是否会被视为幻数?
例如:
arrayOfNumbers[6] // Is six a magic number in this case?
我问这个问题,因为我的一位教授坚持认为程序中的所有字面数字都是魔数。我只是使用实数来访问数组的元素,而不是为每个元素使用命名常量。
谢谢!
答案 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
的声明,我们会进一步了解其类型(例如int
或double
)。
但如果你说:
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之外的所有值都被视为幻数。我的观点一直是,如果恒定值是显而易见的,或者可能不会改变,那么将其留作数字。如果有疑问,可以创建一个独特的常数,因为长期维护会更容易。