我无法理解:
之间有什么区别#define WIDTH 10
和
int width = 10;
使用第一个或第二个有什么好处?
答案 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就像一个静态全局定义范围。请勿将其作为普通变量进行更改或覆盖。