这里C编程指南和编码标准说,我们必须从程序避免幻数,并使用宏幻数为什么我们要避免编程中的Magic Numbers或Constants并使用宏?
在宏会花费更多的时间来评估作为比较常量这样的表现是神奇的号码或更多更好常量。
为例
for(i=0;i<255;i++)
{
}
我们用这个
#define MAX 255
for(i=0;i<MAX;i++)
{
}
第二个是需要更多的时间比较第一个,为什么我们更喜欢第二个按照编码标准。
这里C编程指南和编码标准说,我们必须从程序避免幻数,并使用宏幻数为什么我们要避免编程中的Magic Numbers或Constants并使用宏?
在宏会花费更多的时间来评估作为比较常量这样的表现是神奇的号码或更多更好常量。
为例
for(i=0;i<255;i++)
{
}
我们用这个
#define MAX 255
for(i=0;i<MAX;i++)
{
}
第二个是需要更多的时间比较第一个,为什么我们更喜欢第二个按照编码标准。
使用宏常量不需要更多时间。 #define
是preprocessor指令,所以在二进制代码中,这两段代码会编译成相同的东西!
但是,由于maintainability的原因,我们避免使用'幻数',假设您有许多相同大小的循环和数组,如果将来这个大小发生变化,您需要搜索代码并将其更改,[只有它!],而如果使用预处理器命令,则只需更改它[预处理器命令]。
这两段代码将被编译为相同的东西。当预处理器运行时,MAX
的实例被替换为255,因此编译器正在使用完全相同的代码。
使用#define
或恒定的好处是,如果该值在多个地方使用,且必须chaned出于某种原因,是微不足道的改变#define
,而不是找到正在使用的值的所有地方和改变他们。
第二个是优选的,因为读出循环时给出的含义。对于有人进来并维护你在第一个例子中写的代码,显而易见的问题是“为什么255”?这是什么意思,如果我修改它会发生什么?给这个值起个名字就更清楚了,并且定义它。如果在整个程序中使用相同的号码,只需要在一个地方进行修改。
至于这样做的成本,它很小。在编译时,MAX的所有实例都将被替换为255.在运行时,没有成本。
这是关于主流,而不是性能。任何时候你为同一目的重复两次相同的数字,它应该放在变量,宏或常量中。阅读DRY;代码或值的重复大大增加了未来错误的可能性。
我相信宏在编译时被扩展,而不是运行时,所以根本没有性能损失。即使有一个常量,也没有可测量的差异 - 我相信不到一个周期。
还查找过早优化。
编译C程序时,程序首先由C预处理器处理。它处理程序中的所有#foo
东西,并替换宏。当编译器看到代码时,您的宏已被替换为值。
因此,如果您将第二个代码片段提供给编译器,那么实际的 C编译器将会看到与第一个代码片段中完全相同的内容。这意味着使用宏而不是而不是会减慢您的程序。
有关使用宏(或常量)的想法是让您的数字具有可能对人类有意义的名称。
考虑你的程序支持三辆自行车(或其他,无所谓)。你需要在很多地方写3
(比如你在for
循环中写了255)。但一个月后,当你看到它时,你可能还记得一个3的更多含义。如果您改为:
#define MAX_BICYCLES 3
然后在各处使用MAX_BICYCLES
意图变得更清楚。更好的是,一旦你的应用程序支持5辆自行车,它可能就像改变一个宏一样简单。您不必记住在哪个地方将3
更改为5
。
如果发生了数字变化或数字显然是错误的,您会如何知道?
而不是幻数使用一个真正的名字,意味着什么。
您可以使用#define或常量或枚举作为名称。
哪一个是设计选择。
例如:
#define PRESIDENT_WENT_CRAZY (22)
const int WE_GOOFED= 19;
enum {
THEY_DIDNT_PAY= 16
};
if (PRESIDENT_WENT_CRAZY == foo) { start_thermo_nuclear_war(); }
else if (WE_GOOFED == foo) { refund_lotso_money(); }
else if (THEY_DIDNT_PAY == foo) { infinite_loop(); }
else { happy_days_i_know_why_im_here(); }
现在是不是更好?
const和enum选项是可取的,因为在调试调试器时有足够的信息来显示值和标签。
“在宏中,它需要更多的时间来评估与常量比较”不,它不会。除非你讲的是编译时间,可能会稍微长一些。 –
1:幻数不传达作者的意思,2:幻数,重复时,需要更多时间更改 – Ptival
http://en.wikipedia.org/wiki/Magic_number_(programming)#Unnamed_numerical_constants –