#define和const有什么区别?

66
6个回答

115
#define 指令是一个预处理器指令;在编译器看到代码之前,预处理器就将这些宏替换为它们的实际内容。可以把它看作是源代码自动搜索和替换。
const 变量声明实际上在语言中声明了一个变量,您可以像使用真正的变量一样使用它:获取其地址、传递它、使用它、转换它等等。
关于性能方面:如果您认为避免变量声明可以节省时间和空间,那么要知道,在任何合理的编译器优化级别下,常量值已经在编译时被替换并折叠,因此不会有区别。但是使用 const 变量具有类型检查和使您的代码对调试器变得明确的巨大优势,所以真的没有理由不使用 const 变量。

37
重要的一点是预处理器宏没有作用域,而 const 值具有作用域。 - Fred Larson
2
@Fred:除此之外,还有更多——没有类型检查甚至语法检查。它只是纯文本替换。在#define与const的二分法中,宏只是将文字面量粘贴到代码中... - Kerrek SB
由于使用const会为编译器带来查找开销(我是对的吗?),所以对于像数学π这样的值,#DEFINE会更好(因为该值仅在编译前被替换)。 - afaolek
2
@afaolek:测试并比较汇编代码,任何一个好的编译器都会尽可能地替换常数,所以不应该有任何区别。(而且使用宏定义时,编译器每次都需要解析、词法分析和编目录字面量。) - Kerrek SB
3
似乎使用const#define更可取 - 那么为什么几乎所有的C代码库都广泛使用#define,例如在头文件中,而不是const - Corel

12

#define 创建一个可以被宏预处理器替换的实体,与常量有很大不同,因为根据你定义的内容,它可能会或者不会被视为常量。#define 的内容可以是任意复杂的,经典示例如下:

#define SQR(x) (x)*(x)

然后如果使用:

SQR(2+3*4)

那将被转换为:

(2+3*4)*(2+3*4)

4
# define与const的区别在于,# define由预处理器处理,相当于简单的文本替换。这样定义的常量值对于实际编译器不可见,而使用const修饰符定义的变量是一个实际的类型“变量”(虽然并不真正是变量)。# define的缺点是它替换了名称的每个出现,而const变量得到正常的查找,因此你有更少的命名冲突风险,而且它不是类型安全的。
# define的优点在于它保证了常数性,因此不会有后备变量。常量变量可能会被替换到代码中,所以在某些情况下# define可能会更快。然而,一个好的编译器应该无论如何都会内联这些常量,并且在大多数情况下不太可能有太大的差异,因此我会继续使用const,除非你有一段代码,在其中你已经看到编译器没有内联变量,并且它是非常、非常重要的性能关键代码。

1

#define 是文本替换,因此速度非常快。此外,它保证了常量性。缺点是它不是类型安全的。

另一方面,const 变量可能会或可能不会在代码中被替换为内联。您可以强制取消 const 属性,使其在内存中(尽管它可能最初就驻留在只读内存中,但无论哪种方式都会带来麻烦)。但是,它保证是类型安全的,因为它携带自己的类型。

我个人建议使用 const 来明确您的意图。


你不能合法地取消常量变量的const属性,而非法地这样做会强制其进入内存是未定义的。 - Mike Seymour
当然可以,不过结果是否属于未定义行为另说。这就是我的意思,使用const并不能阻止它的发生。 - Blindy
@Blindy:好的,但是你的回答说它会强制将其加载到内存中,但这并不一定。它可以在正确使用时继续将其内联,并忽略任何尝试更改它的操作;实际上,这正是我的编译器所做的(至少有些时候)。 - Mike Seymour
你可以合法地获取一个常量变量的地址,并将其强制存储到内存中。这是可以通过#define避免的。 - Mike Seymour
那确实是另一种打破const的方式,但是即使转换const类型也应该消除您可以执行的任何内联。我不记得我在哪里读过它。 - Blindy
@Blindy:不,试图通过强制转换去除“const”会导致未定义的行为,因此你不能说它“应该”做任何事情。你可能已经读到了一个特定实现将其放置在内存中并允许你修改它的情况;其他实现则不会这样做。 - Mike Seymour

1

DEFINE是预处理指令,例如#define x 5。编译器将获取该值并在程序中调用x的任何位置插入它,并生成目标文件。定义常量不会在符号表中创建符号条目。如果您想要调试程序,则找不到x。我认为应尽可能使用常量。


0

#define A B 告诉预处理器(编译器的一部分)在编译代码之前将 B 替换为 A。你可以(虽然这是一个可怕的想法)做一些像 #define FALSE TRUE 的事情。

const 变量意味着一旦变量被设置,它就不能被更改,但它不会对预处理器做任何事情,并且受到变量的正常规则的约束。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接