【问题标题】:In C++, is it better to use #define or const to avoid magic numbers?在 C++ 中,使用 #define 还是 const 来避免幻数更好?
【发布时间】:2013-11-06 02:34:08
【问题描述】:

使用#define 优于 const 有哪些优点和缺点(反之亦然)?

当我读到关于糟糕的编程实践,特别是幻数时,我发现自己更频繁地使用#define。一些问题突然出现在我的脑海中,例如:

经常使用#define 是不是很糟糕?
是否占用内存空间?
改用 const 会更快吗?

我读过一些关于这个的信息,但我仍然不确定,根据我的理解:
#define 定义了一个宏(不确定宏是什么意思),它处理预处理。在处理代码之前,它会将已定义关键字的所有实例替换为其他内容。另一方面, const 是变量,其值不能在运行时中途更改。

我能想到使用 const 的唯一原因是该值是否依赖于其他变量。例如:

#define PI 3.14159f
#define RADIUS 3.0f
#define AREAOFCIRCLE PI*RADIUS*RADIUS

效率会很低,因为 AREAOFCIRCLE 的每个实例都将被 PI*RADIUS*RADIUS 替换,因此程序会在您每次使用 AREAOFCIRCLE 时为其计算。另一方面:

const float areaofcircle = PI*RADIUS*RADIUS;

会更有效,因为程序只会计算一次。

那么回到最初的问题,#define 与 const 相比如何?

【问题讨论】:

标签: c++ constants c-preprocessor


【解决方案1】:

在这种情况下不必担心效率,因为所有这些都将在编译时计算。

您应该尽可能停止使用宏(至少定义常量)。宏是针对名称空间和范围的狂野事物。另一方面,const 对象具有 type,这可以减少意外错误。

阅读 Stroustrup 的建议总是很有用的:"So, what's wrong with using macros?"

【讨论】:

  • “所有这些都在编译时计算”是什么意思。什么意思?
  • 不管你使用的是宏还是常量,在这两种情况下PI*RADIUS*RADIUS 的结果都将在编译时计算,最终值将被替换为赋值。
  • 那么这是否意味着#define AREAOFCIRCLE PIRADIUSRADIUS 只会由程序计算一次,而不是每次调用 AREAOFCIRCLE 时计算?
  • 是的,在运行时,您在使用AREAOFCIRCLE 的任何地方都有计算值。
  • 用于定义清单常量的宏具有类型。对于#define SIZE 1SIZE 的类型为int
【解决方案2】:

C++ 中的“const”是无价的。 Consts 在表达式中强制执行类型检查,而“#define”d 常量只是被扩展。

此外,由于常量是类型化的,编译器可能会干扰更好的优化,而定义它必须猜测(1.0 是浮点数还是双精度数?使用后缀作为 1.0d 或 1.0f 可能会有所帮助,但我很少看到写实数如此有意识地......)。

所以使用 consts 来定义常量

const float PI = 3.14159f;
const float RADIUS = 3.0f;
const float AREAOFCIRCLE = PI*RADIUS*RADIUS;

您将获得至少相同的编译时间优化 + 一些额外的类型检查。

【讨论】:

  • 1.0 是双倍的。没什么好猜的。
【解决方案3】:

"const" 更有效,因为它占用内存一次并且在每个地方都被引用。相比之下,“#define”在任何使用它的地方都会占用空间和加法操作。

【讨论】:

  • 为什么#define 会占用空间?我以为它只进行文字替换?
  • 使用#define时,可能会根据编译器产生加法运算
  • 我的意思是在使用替换的地方,它会占用内存。
猜你喜欢
  • 1970-01-01
  • 2013-10-24
  • 1970-01-01
  • 1970-01-01
  • 2021-09-14
  • 1970-01-01
  • 2017-10-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多