我知道-1
、0
、1
和2
是幻数规则的例外。但是,我想知道当它们是漂浮物时是否也是如此。我是否必须为它们初始化一个最终变量,或者我可以直接在我的程序中使用它们。
我在课堂上将其用作百分比。如果输入小于 0.0 或大于 1.0,那么我希望它自动将百分比设置为零。所以如果(0.0 <=输入&&输入<= 1.0)。
谢谢
这些数字并不是幻数规则的真正例外。常识规则(只要有"一个"规则),当它没有简化到教条的水平时,基本上是,"不要在不能使其含义显而易见的上下文中使用数字。碰巧的是,这四个数字在明显的上下文中非常常用。这并不意味着它们是唯一适用的数字,例如,如果我有:
long kilometersToMeters(int km) { return km * 1000L; }
命名这个数字真的没有意义:从微小的上下文中可以明显看出它是一个转换因子。另一方面,如果我在一些低级代码中执行此操作:
sendCommandToDevice(1);
这仍然是错误的,因为这应该是一个恒定的kResetCommand = 1
或类似的东西。
因此,0.0
和1.0
是否应该被常量完全替换为常量完全取决于上下文。
这实际上取决于上下文。避免幻数的全部意义在于保持代码的可读性。使用您的最佳判断,或向我们提供一些背景信息,以便我们可以使用我们的判断。
幻数[u]nique values with unexplained meaning or multiple occurrences which could (preferably) be replaced with named constants
.
http://en.wikipedia.org/wiki/Magic_number_(编程)
编辑:何时使用变量名称记录代码与何时仅使用数字是一个激烈争论的话题。我的观点是上面链接的 Wiki 文章的作者的观点:如果含义不是很明显,并且在您的代码中多次出现,请使用命名常量。如果它只发生一次,只需注释代码。
如果您对其他人的(强烈偏见)意见感兴趣,请阅读什么是自记录代码,它可以取代记录良好的代码吗?
通常,每个规则都有例外(这个规则也是如此)。对这些常量使用一些助记符名称是一个风格问题。
例如:
int Rows = 2;
int Cols = 2;
是一个非常有效的例子,其中使用原始值会具有误导性。
从上下文来看,幻数的含义应该是显而易见的。如果不是 - 给这个东西一个名字。
为某物附加名称会创建一个标识。 给定定义
const double Moe = 2.0;
const double Joe = 2.0;
...
double Larry = Moe;
double Harry = Moe;
double Garry = Joe;
对Moe和Joe使用符号表明,拉里和哈利的默认值彼此相关,而Garry的默认值则不是。 是否为特定常量定义名称的决定不应取决于该常量的值,而应取决于它是否会在代码中非巧合地出现在多个位置。 如果一个人正在与远程设备通信,需要向其发送特定的字节值以触发重置,我会考虑:
void ResetDevice()
{
// The 0xF9 command is described in the REMOTE_RESET section of the
// Frobnitz 9000 manual
transmitByte(0xF9);
}
... elsewhere
myDevice.ResetDevice();
...
otherDevice.ResetDevice();
在许多情况下优于
// The 0xF9 command is described in the REMOTE_RESET section of the
// Frobnitz 9000 manual
const int FrobnitzResetCode = 0xF9;
... elsewhere
myDevice.transmitByte(FrobnitzResetCode );
...
otherDevice.transmitByte(FrobnitzResetCode );
0xF9的值在重置 Frobnitz 9000 设备的上下文之外没有实际意义。 除非出于某种原因,外部代码应该更喜欢发送必要的值本身而不是调用 ResetDevice 方法,否则常量对方法外部的任何代码都没有价值。 虽然也许可以使用
void ResetDevice()
{
// The 0xF9 command is described in the REMOTE_RESET section of the
// Frobnitz 9000 manual
int FrobnitzResetCode = 0xF9;
transmitByte(FrobnitzResetCode);
}
在如此狭窄的背景下为事物定义一个名称真的没有多大意义。
像 0 和 1 这样的值唯一"特别"的是,在使用它们的上下文之外没有特定于域的标识的情况下,它们比其他常量(例如 23)更频繁地使用。 如果使用的函数要求第一个参数指示附加参数的数量(在 C 中有点常见),最好说:
output_multiple_strings(4, "Bob", Joe, Larry, "Fred"); // There are 4 arguments
...
output_multiple_strings(4, "George", Fred, "James", Lucy); // There are 4 arguments
比 #define NUMBER_OF_STRINGS 4//有 4 个参数
output_multiple_strings(NUMBER_OF_STRINGS, "Bob", Joe, Larry, "Fred");
...
output_multiple_strings(NUMBER_OF_STRINGS, "George", Fred, "James", Lucy);
后一条语句意味着传递给第一个方法的值与传递给第二个方法的值之间的联系比传递给第一个方法的值与该方法调用中的其他任何值之间存在的联系更强。 除此之外,如果需要将其中一个调用更改为传递 5 个参数,则在第二个代码示例中不清楚应该更改什么以允许这样做。 相比之下,在前一个样本中,常量"4"应更改为"5"。