在许多程序中,#define
的作用与常量相同。例如。
#define FIELD_WIDTH 10
const int fieldWidth = 10;
我经常看到第一种形式优先于另一种形式,依靠预处理器来处理基本上是应用程序的决定。这个传统有原因吗?
答案 0 :(得分:152)
这有一个非常可靠的原因:C中的const
并不意味着某些东西是不变的。它只是意味着变量是只读的。
在编译器需要真常量的地方(例如非VLA数组的数组大小),使用const
变量(例如fieldWidth
)是不可能的。
答案 1 :(得分:20)
他们是不同的。
const
只是一个限定符,它表示变量在运行时无法更改。但变量的所有其他功能仍然存在:它已分配存储,并且可以解决此存储。所以代码不只是将它视为文字,而是通过访问指定的内存位置来引用变量(除非它是static const
,然后它可以被优化掉),并在运行时加载它的值。并且由于const
变量已分配存储空间,如果将其添加到标题并将其包含在多个C源中,除非将其标记为extern
,否则会出现“多符号定义”链接错误。在这种情况下,编译器无法根据实际值优化代码(除非启用了全局优化)。
#define
只是用名称替换名称。此外,预处理器中可以使用#define
'常量:您可以将其与#ifdef
一起使用,根据其值进行条件编译,或者使用字符串化运算符#
来获取字符串及其值。当编译器在编译时知道它的值时,它可以根据该值优化代码。
例如:
#define SCALE 1
...
scaled_x = x * SCALE;
当SCALE
定义为1
时,编译器可以消除乘法,因为它知道x * 1 == x
,但SCALE
是extern
} { {1}},它需要生成代码来获取值并执行乘法,因为在链接阶段之前不会知道该值。 (const
需要使用来自多个源文件的常量。)
与使用extern
相当的更接近的是使用枚举:
#define
但这仅限于整数值,并且没有enum dummy_enum {
constant_value = 10010
};
的优点,所以它没有被广泛使用。
#define
非常有用。或者如果它与指针一起使用。或者,如果它是通过变量索引值访问的常量值数组。否则,const
优于const
。
答案 2 :(得分:13)
原因在于,大多数情况下,您需要一个常量,而不是const
- 限定变量。这两者在C语言中并不相同。例如,变量作为static
- storage-duration对象的初始值设定项的一部分无效,作为非vla数组维度(例如结构中数组的大小,或C99之前的任何数组)。 / p>
答案 3 :(得分:8)
扩展R的答案:fieldWidth
不是常量表达式;它是一个const
- 限定变量。它的值直到运行时才建立,因此不能在需要编译时常量表达式的地方使用它(例如在数组声明中,或switch
中的案例标签声明等)。
与宏FIELD_WIDTH
比较,后预处理扩展为常量表达式10
;此值在编译时已知,因此可用于数组维度,案例标签等。
答案 4 :(得分:6)
要添加到R.和Bart的答案:在C中只有一种方法可以定义符号编译时常量:枚举类型常量。该标准规定这些类型为int
。我个人会把你的例子写成
enum { fieldWidth = 10 };
但我猜C程序员的口味差异很大。
答案 5 :(得分:4)
虽然const int并不总是合适的,但是如果你定义的是一个整数值,枚举通常可以作为#define的替代。在这种情况下,这实际上是我的偏好。
enum { FIELD_WIDTH = 16384 };
char buf[FIELD_WIDTH];
在C ++中,这是一个巨大的优势,因为您可以将枚举范围限定在类或命名空间中,而不能使用#define。
在C中你没有命名空间,也不能在结构中使用枚举范围,甚至不确定你是否获得类型安全性,所以我实际上看不到任何主要优势,尽管可能有些C程序员会指出它对我说。
答案 6 :(得分:2)
根据K& R(第2版,第211页),“const和volatile属性是ANSI标准的新特性”。这可能意味着真正的旧ANSI代码根本就没有这些关键字,这实际上只是传统问题。 此外,它表示编译器应检测更改const变量的尝试,但除此之外,它可能会忽略这些限定符。我认为这意味着某些编译器可能不会优化包含const变量的代码在机器代码中表示为中间值(如#define),这可能需要额外的时间来访问远程内存并影响性能。
答案 7 :(得分:1)
某些C编译器会将所有const
变量存储在二进制文件中,如果准备a large list of coefficients,则可能会占用嵌入式世界中的大量空间。
相反:使用const
允许在现有程序上闪烁以更改特定参数。
答案 8 :(得分:0)
在C中定义数字常量的最佳方法是使用 enum 。阅读K& R的C编程语言的相应章节,第39页。