C++ 为什么使用#define 而不是变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6004963/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 19:19:01  来源:igfitidea点击:

Why use #define instead of a variable

c++c-preprocessor

提问by Greener

What is the point of #definein C++? I've only seen examples where it's used in place of a "magic number" but I don't see the point in just giving that value to a variable instead.

#defineC++的重点是什么?我只看到过用它代替“幻数”的例子,但我不认为只将该值赋予变量有什么意义。

采纳答案by Paul Tomblin

Mostly stylistic these days. When C was young, there was no such thing as a const variable. So if you used a variable instead of a #define, you had no guarantee that somebody somewhere wouldn't change the value of it, causing havoc throughout your program.

这些天主要是文体。在 C 年轻的时候,没有 const 变量这样的东西。因此,如果您使用变量而不是 a #define,则无法保证某处有人不会更改它的值,从而在整个程序中造成严重破坏。

In the old days, FORTRAN passed even constants to subroutines by reference, and it was possible (and headache inducing) to change the value of a constant like '2' to be something different. One time, this happened in a program I was working on, and the only hint we had that something was wrong was we'd get an ABEND (abnormal end) when the program hit the STOP 999that was supposed to end it normally.

在过去,FORTRAN 甚至通过引用将常量传递给子例程,并且可能(并且会引起头痛)将诸如“2”之类的常量的值更改为不同的值。有一次,这发生在我正在处理的程序中,我们得到的唯一错误提示是当程序遇到STOP 999应该正常结束的 ABEND(异常结束)。

回答by supercheetah

The #defineis part of the preprocessor language for C and C++. When they're used in code, the compiler just replaces the #definestatement with what ever you want. For example, if you're sick of writing for (int i=0; i<=10; i++)all the time, you can do the following:

#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
}

If you want something more generic, you can create preprocessor macros:

如果你想要更通用的东西,你可以创建预处理器宏:

#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
}

It's also very useful for conditional compilation (the other major use for #define) if you only want certain code used in some particular build:

#define如果您只想在某些特定构建中使用某些代码,它对于条件编译( 的另一个主要用途)也非常有用:

// compile the following if debugging is turned on and defined
#ifdef DEBUG
// some code
#endif

Most compilers will allow you to define a macro from the command line (e.g. g++ -DDEBUG something.cpp), but you can also just put a define in your code like so:

大多数编译器允许您从命令行定义宏(例如g++ -DDEBUG something.cpp),但您也可以像这样在代码中放置一个定义:

#define DEBUG

Some resources:

一些资源:

  1. Wikipedia article
  2. C++ specific site
  3. Documentation on GCC's preprocessor
  4. Microsoft reference
  5. C specific site(I don't think it's different from the C++ version though)
  1. 维基百科文章
  2. C++ 特定站点
  3. GCC 预处理器的文档
  4. 微软参考
  5. C 特定站点(不过我认为它与 C++ 版本没有区别)

回答by Harpee

I got in trouble at work one time. I was accused of using "magic numbers" in array declarations.

有一次我在工作中遇到了麻烦。我被指控在数组声明中使用“幻数”。

Like this:

像这样:

int Marylyn[256], Ann[1024];

The company policy was to avoid these magic numbers because, it was explained to me, that these numbers were not portable; that they impeded easy maintenance. I argued that when I am reading the code, I want to know exactly how big the array is. I lost the argument and so, on a Friday afternoon I replaced the offending "magic numbers" with #defines, like this:

公司的政策是避免使用这些神奇数字,因为有人向我解释说,这些数字不可移植;它们妨碍了简单的维护。我争辩说,当我阅读代码时,我想确切地知道数组有多大。我失去了争论,因此,在星期五下午,我用 #defines 替换了有问题的“魔术数字”,如下所示:

 #define TWO_FIFTY_SIX 256
 #define TEN_TWENTY_FOUR 1024

 int Marylyn[TWO_FIFTY_SIX], Ann[TEN_TWENTY_FOUR];

On the following Monday afternoon I was called in and accused of having passive defiant tendencies.

在接下来的星期一下午,我被叫来并指责我有被动的挑衅倾向。

回答by Puppy

#definecan accomplish some jobs that normal C++ cannot, like guarding headers and other tasks. However, it definitely should not be used as a magic number- a static const should be used instead.

#define可以完成一些普通 C++ 无法完成的工作,比如保护头文件和其他任务。但是,它绝对不应该用作幻数 - 应该使用静态常量。

回答by Puppy

C didn't use to have consts, so #defines were the only way of providing constant values. Both C and C++ do have them now, so there is no point in using them, except when they are going to be tested with #ifdef/ifndef.

C 过去没有常量,所以#defines 是提供常量值的唯一方法。C 和 C++ 现在都有它们,所以使用它们没有意义,除非它们将用 #ifdef/ifndef 进行测试。

回答by YXD

Most common use (other than to declare constants) is an include guard.

最常见的用途(除了声明常量之外)是包含保护

回答by DanJ

Define is evaluated before compilation by the pre-processor, while variables are referenced at run-time. This means you control how your application is built (not how it runs)

定义在编译前由预处理器评估,而变量在运行时被引用。这意味着您可以控制应用程序的构建方式(而不是它的运行方式)

Here are a couple examples that use define which cannot be replaced by a variable:

以下是使用不能被变量替换的定义的几个示例:

  1. #define min(i, j) (((i) < (j)) ? (i) : (j))
    note this is evaluated by the pre-processor, not during runtime

  2. http://msdn.microsoft.com/en-us/library/8fskxacy.aspx

  1. #define min(i, j) (((i) < (j)) ? (i) : (j))
    注意这是由预处理器评估的,而不是在运行时

  2. http://msdn.microsoft.com/en-us/library/8fskxacy.aspx

回答by charley

The #defineallows you to establish a value in a header that would otherwise compile to size-greater-than-zero. Your headers should not compile to size-greater-than-zero.

#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?

EDIT: As Neil points out in the comment to this post, the explicit definition-with-value in the header would work for C++, but not C.

编辑:正如 Neil 在对这篇文章的评论中指出的那样,标题中的显式定义与值适用于 C++,但不适用于 C。