2010-01-18 19 views
7

我是一个相当新的程序员,我很抱歉如果这些信息很容易找到,我还没有找到它。数组中的魔术数字? - C++

我的问题是:

是被认为是神奇数字,当你使用文字号码访问数组的特定元素?

例如:

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

我问这个问题,因为我的一个教授坚持认为,程序中的所有文字数字是幻数。对我来说,使用实数来访问数组的元素将会很好,而不是使用每个元素的命名常量。

谢谢!

+1

'#define ONE 1' ...'i + = ONE;' – 2010-01-18 21:46:56

+2

为了避免这种情况,上帝给了我i ++:P – Leo 2010-01-18 21:48:07

+1

是的。 6是一个幻数。在代码中避免幻数总是比较好的,例如:#define PI 3.1416',如果pi的值发生变化,比在整个代码中使用3.1416更好。 – 2010-01-18 21:48:33

回答

22

这真的取决于上下文。如果你有这样的代码:

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

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

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

...然后6确切地说是一个幻数。

+0

Ahh,O.K.这就说得通了。 – Alex 2010-01-18 22:11:58

5

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

0

如果您需要访问数组中的特定元素,您可能会犯错。

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

6

这很神奇。

我的意思是,为什么在访问第6个元素?什么是应该应用于这个数字的语义?就目前而言,我们所知的只是“第六(零基)”号码。如果我们知道arrayOfNumbers的声明,我们会进一步知道它的类型(例如,intdouble)。

但是,如果你说:

arrayOfNumbers[kDistanceToSaturn]; 

...现在有更多的含义,有人阅读的代码。

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

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

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

另一个问题是“arrayOfNumbers”没有告诉我们有关数组的内容。我们已经知道它的一系列数字,因为我们看到了某处的声明,在那里您说int arrayOfNumers[12345];或您声明了它。相反,如下所示:

int distanceToPlanetsFromSol[kNumberOfPlanets]; 

...给了我们一个关于数据实际是什么以及它的语义是什么的更好的概念。你作为程序员的目标之一应该是编写以这种方式自我记录的代码。

,然后我们可以在其他地方认为,如果kNumberOfPlanets应该是8或9 :)

+0

那么这取决于你是否计算了两次火星。 – 2010-01-19 01:59:15

0

这只是不是一个神奇的数字,如果你的程序是做涉及老六特别很特别的东西。你能提供一些背景吗?

1

您必须为有意义的答案提供更多上下文。并非所有的文字数字都是魔法,但很多都是。在这样的情况下,根本没有办法可以肯定地说,尽管大多数情况下,我可以用一个明确的数组索引>> 1来考虑可能是魔术。

0

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

+0

然后你应该使用命名常量,而不是幻数。 – 2010-01-18 21:48:28

+0

该死的写下你刚才写的东西。 +1。 – 2010-01-18 21:49:27

1

不是全部程序中的文字确实符合“神奇数字”的要求 - 但这似乎确实如此。 6不让我们知道为什么你要访问数组中的特定元素。

不是是一个神奇数字,即使在第一次检查(或至少是最小的检查)时,它的含义也需要很清楚。举个例子来说,很多代码会做这样的事情:&x[0]。在这种情况下,通常非常清楚的是,'0'的确意味着“数组的开始”。

0

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

2

另一种方式来看待它:

如果以后有机会的一些程序需要访问7元而不是6?你会或维护者知道吗?例如,如果如果第6项是在CA树木计数这将是一件好事,把

#define CA_STATE_ENTRY 6 

那么,如果现在表被重新排序有人能看到,他们需要把这个改为9(说) 。顺便说一句我并不是说这是按状态维护树数的最佳方法 - 它可能不是。

同样,如果以后人们想改变计划,以应对在俄勒冈州的树木,然后他们知道,以取代

trees[CA_STATE_ENTRY] 

trees[OR_STATE_ENTRY] 

的一点是

trees[6] 

不是自我记录

当然,对于C++而言,它应该是enum而不是#define

0

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