#Define VS Variable

时间:2012-06-18 08:43:59

标签: c variables c-preprocessor

我无法理解:

之间有什么区别
#define WIDTH 10 

int width = 10;

使用第一个或第二个有什么好处?

6 个答案:

答案 0 :(得分:8)

  

两者有什么区别?

第一个是 Macro ,第二个是变量声明。

#define WIDTH 10 preprocessor directive ,可让您指定名称(WIDTH)及其替换文字(10)。预处理器解析源文件,每次出现的名称都被其关联的文本替换。编译器根本不会实际看到宏名称,它看到的是被替换的文本。

变量声明由编译器本身评估。它告诉编译器声明一个名为width且类型为int的变量,并使用值10对其进行初始化。
编译器通过自己的名称width知道此变量。

  

您更喜欢哪一个?为什么?

通常,建议在#define上使用编译时常量变量。 所以你的变量声明应该是:

const int width = 10;

选择#define上的编译时常数有很多原因,即:

基于范围的机制:

#define的范围仅限于定义它的文件。因此,在一个源文件中创建的#defines在不同的源文件中可用 NOT 。简而言之,#define s不尊重范围。请注意const变量可以作用域。它们遵守所有范围规则。


在编译错误期间避免奇怪的魔法数字:

如果您正在使用#define那些在预编译时被预处理器取代那么如果您在编译期间收到错误,那将会引起混淆,因为错误消息不会引用宏名称而是值和它会出现突然的价值,而且会浪费很多时间在代码中跟踪它。


易于调试:

同样出于与#2中提到的相同的原因,虽然调试#define实际上没有提供任何帮助。

答案 1 :(得分:7)

嗯,有很大的不同。您可以更改width的值,您可以获取其地址,您可以询问其大小等。对于WIDTH,它将在任何地方用常量10替换,因此表达式++WIDTH没有任何意义。在另一方面,您可以使用WIDTH项声明一个数组,而不能使用width项声明数组。

总结:WIDTH的值在编译时是已知的,无法更改。编译器不为WIDTH分配内存。相反,width初始值为10的变量,其进一步的值在编译时是未知的;变量从编译器中获取内存。

答案 2 :(得分:2)

WIDTH是一个宏,它将被preprocessor替换为值(10),而width是一个变量。

当你#define一个宏(比如这里的WIDTH)时,预处理器只会在程序传递给编译器之前执行 text-replacement 。即,只要您在代码中使用WIDTH,就会将其替换为10

但是当你int width=10时,变量是活着的

答案 3 :(得分:0)

首先是简短背景:在编译之前,C文件已预处理预处理器会检查#include#define语句。

在您的情况下,#define语句告诉预处理器使用字符串WIDTH更改源代码中的每个字符串10。当文件在下一步中获得编译时,WIDTH的每次出现实际上都是10。现在,区别

#define WIDTH 10 

int width = 10;

是第一个可以看作constant值,而第二个是正常变量,其值可以改变。

答案 4 :(得分:0)

一个#define由预处理器处理,如果在源代码中找到WIDTH并用10替换它,它所做的只是其他事情的基本替换,另一个{ {1}}由编译器处理,这将在查找表中创建条目,生成二进制文件以在堆栈上分配足够的内存,具体取决于其定义位置,并将值10复制到该内存位置。

因此,一个只不过是常量的标签,另一个是运行时的变量。

您可以使用预处理器来加快执行速度,因为变量需要在堆栈上分配,代价是在运行时不可变。

您通常使用预处理器来处理在运行时不需要更改的事情,但要小心预处理器调试可能有点棘手,因为它们实际上可以在将源代码传递给编译器之前对其进行操作,从而导致非常微妙的错误,可能会或可能不会检查源代码。

答案 5 :(得分:0)

Define就像一个静态全局定义范围。请勿将其作为普通变量进行更改或覆盖。