1

以 C/C++ 中的以下代码为例:

int foo[] = {0, 0, 0, 0};

没有神奇的数字,对吧?
现在,Python“等效”将是:

foo = [0, 0, 0, 0]

仍然没有神奇的数字。
然而,在 Python 中,同样的事情可以这样写:

foo = [0] * 4

现在我们确实有一个神奇的数字。还是我们?
我猜这和其他类似的东西出现在这些和其他语言上。

4

5 回答 5

11

不是每个数字都是一个神奇的常数。原因4和四个0是神奇的数字(在任何语言中)是完全不清楚为什么这个数字是4而不是任何其他数字。

例如,在使用众所周知的六面骰子进行的游戏中

def roll_die():
    return random.randint(1,6)

这段代码没有神奇的数字,因为很容易看出数字的来源。

另一方面,很难猜测其他程序员知道哪些数字。例如,并不是每个人都知道一副牌中有多少张牌,所以在那里使用命名常量更有意义。

一个数字是否“神奇”完全取决于上下文,它与语言无关。如有疑问,为安全起见命名常量。

于 2011-03-16T00:27:48.300 回答
5

这与(在 C 或 C++ 中)有何不同:

int foo[4] = {0};

?

在所有这些情况下,数组的大小都是一个神奇的数字。

于 2011-03-16T00:07:22.147 回答
0

以我理解的方式,幻数是域值(用于计算,映射元素中的索引)。他们的想法在任何语言中都是一致的。在您的示例中,这取决于这些数组的用途。

于 2011-03-16T00:08:58.540 回答
0

请参阅下面的代码。它是交流语言功能。

  int arr[] = { [0 ... 4]=3,[7]=7,[8 ... 12]=12,[15]=0};

int arr[] = { 3, 3, 3, 3, 3, 0, 0, 7, 12, 12, 12, 12, 12, 0, 0, 0 };

于 2011-03-16T04:31:49.200 回答
-1

您的所有问题都表明,“幻数”的概念和禁止在程序中使用“幻数”的规则是完全愚蠢的。对于不了解自己在做什么的人来说,针对幻数的规则是很差的近似值,对于在多个地方硬编码必须一致或相互依赖的值的更明智的规则。例如,这段代码是完全合理的,只要缓冲区长度不需要匹配程序或现实世界中的任何其他内容:

char buf[100];
snprintf(buf, sizeof buf, ...);

但是这段代码非常糟糕:

char buf[100];
snprintf(buf, 100, ...);

当然,在现实世界中,您可能希望缓冲区大小匹配,例如打印某个特定大小的整数所需的最大位数。在这种情况下,您可能需要以下内容:

char buf[3*sizeof(int)+3];
snprintf(buf, sizeof buf, ...);

如果您认为CHAR_BIT是可变的,那么您可能希望将 3 替换为CHAR_BIT. 无论如何,表达式中出现的常量都不是“邪恶的幻数”。

在您的示例中,如果数组的维度取决于其他一些变量,那么您的所有三个数组定义都是不好的做法。但如果维度 4 是你所做工作的基础,我认为它没有任何问题。

当然,您所做的事情有时会在代码的生命周期内发生变化,但这就是文档的用途。如果不进行某种程度的修改,就不能期望代码能够处理将来可能发生的目的变更,并且只要您记录了其原始目的和合同是什么,那么更改这些内容的人应该不难找到代码的部分那需要改变。

于 2011-03-16T00:51:09.137 回答