【发布时间】:2011-08-25 16:28:39
【问题描述】:
C++ 中#define 的意义何在?我只看到了使用它代替“幻数”的示例,但我没有看到将值赋给变量的意义。
【问题讨论】:
标签: c++ c-preprocessor
C++ 中#define 的意义何在?我只看到了使用它代替“幻数”的示例,但我没有看到将值赋给变量的意义。
【问题讨论】:
标签: c++ c-preprocessor
有一次我在工作中遇到了麻烦。我被指控在数组声明中使用“幻数”。
像这样:
int Marylyn[256], Ann[1024];
公司的政策是避免使用这些神奇的数字,因为向我解释说,这些数字是不可移植的;他们妨碍了简单的维护。我争辩说,当我阅读代码时,我想确切地知道数组有多大。我失去了争论,所以在一个星期五的下午,我用#defines 替换了令人反感的“幻数”,如下所示:
#define TWO_FIFTY_SIX 256
#define TEN_TWENTY_FOUR 1024
int Marylyn[TWO_FIFTY_SIX], Ann[TEN_TWENTY_FOUR];
在接下来的星期一下午,我被叫来并被指控有消极反抗倾向。
【讨论】:
#define MARYLYN_SIZE 256 是你想要的。
256 和1024 是不可维护的,但是当遇到这个你决定让它变得更糟。如果这种行为继续发生在我的位置上,你就会出局。
static constexpr const size_t MAX_HOMES_AVAILABLE = 1024; int Ann[MAX_HOMES_AVAILABLE];。如果选择真的显而易见且已本地化,那么直接使用 1024 并没有太不好,但做 Harpee 所做的只是拖钓。
#define 允许您在标头中建立一个值,否则该值将编译为大于零的大小。您的标头不应编译为大于零的大小。
// File: MyFile.h
// This header will compile to size-zero.
#define TAX_RATE 0.625
// NO: static const double TAX_RATE = 0.625;
// NO: extern const double TAX_RATE; // WHAT IS THE VALUE?
编辑:正如 Neil 在这篇文章的评论中指出的那样,标头中的显式定义值适用于 C++,但不适用于 C。
【讨论】:
const double TAX_RATE = 0.625。 consts 默认具有翻译单元范围。
#define 是 C 和 C++ 预处理器语言的一部分。当它们在代码中使用时,编译器只需将 #define 语句替换为您想要的任何内容。例如,如果您厌倦了一直写for (int i=0; i<=10; i++),您可以执行以下操作:
#define fori10 for (int i=0; i<=10; i++)
// some code...
fori10 {
// do stuff to i
}
如果您想要更通用的东西,您可以创建预处理器宏:
#define fori(x) for (int i=0; i<=x; i++)
// the x will be replaced by what ever is put into the parenthesis, such as
// 20 here
fori(20) {
// do more stuff to i
}
如果您只想在某些特定构建中使用某些代码,它对于条件编译(#define 的另一个主要用途)也非常有用:
// compile the following if debugging is turned on and defined
#ifdef DEBUG
// some code
#endif
大多数编译器允许您从命令行定义宏(例如g++ -DDEBUG something.cpp),但您也可以像这样在代码中定义:
#define DEBUG
一些资源:
【讨论】:
#define 作为常量。事实上,它被认为是非 C++ 或类似的东西。
#define fori(x) for (int i=0; i<=x; i++) 应改为 #define fori(x) for (int i=0; i<=(x); i++)。 (注意额外的括号。)在这个例子中括号的使用可能并不明显,但是如果有人在参数 x 中进行按位运算,就会发生错误。
Define 在编译前由预处理器求值,而变量在运行时被引用。这意味着您可以控制应用程序的构建方式(而不是运行方式)
这里有几个使用不能被变量替换的define的例子:
#define min(i, j) (((i) 请注意,这是由预处理器评估的,而不是在运行时
【讨论】:
C 过去没有常量,所以#defines 是提供常量值的唯一方法。 C 和 C++ 现在都拥有它们,因此使用它们没有任何意义,除非它们要使用 #ifdef/ifndef 进行测试。
【讨论】:
#define 可以完成一些普通 C++ 无法完成的工作,例如保护标头和其他任务。但是,它绝对不应该用作幻数——应该使用静态常量。
【讨论】:
这些天主要是风格。在 C 语言还很年轻的时候,还没有 const 变量这样的东西。因此,如果您使用变量而不是 #define,则无法保证某个地方的某个人不会更改它的值,从而在整个程序中造成严重破坏。
在过去,FORTRAN 通过引用将常量传递给子例程,并且有可能(并且令人头疼)将像“2”这样的常量的值更改为不同的值。有一次,这发生在我正在处理的一个程序中,我们得到的唯一提示是,当程序遇到应该正常结束的STOP 999 时,我们会得到一个 ABEND(异常结束)。
【讨论】:
最常见的用途(除了声明常量)是include guard。
【讨论】: