我不明白有什么区别:
#define WIDTH 10
和
int width = 10;
使用第一个或第二个有什么好处?
嗯,有很大的不同。你可以改变它的值width
,你可以取它的地址,你可以询问它的大小等等。使用WIDTH
, 它将被替换为一个常量10
,所以表达式++WIDTH
没有任何意义。另一方面,你可以声明一个包含WIDTH
项目的数组,而你不能声明一个包含width
项目的数组。
总结一下: 的值WIDTH
在编译时是已知的,无法更改。编译器不会为WIDTH
. 相反,width
是一个初始值为 10 的变量,其进一步的值在编译时是未知的;变量从编译器获取内存。
两者有什么区别?
第一个是宏,第二个是变量声明。
#define WIDTH 10
是一个预处理器指令,允许您指定名称(WIDTH
)及其替换文本(10
)。预处理器解析源文件,并且每次出现的名称都被其关联的文本替换。编译器实际上根本看不到宏名称,它看到的是替换的文本。
变量声明由编译器本身评估。它告诉编译器声明一个名为width
and 类型的变量,int
并用 value 初始化它10
。
编译器通过它自己的名字知道这个变量width
。
你应该更喜欢哪一个?为什么?
通常,建议使用编译时常量变量 over #define
. 所以你的变量声明应该是:
const int width = 10;
选择编译时间常数的原因有很多#define
,即:
基于范围的机制:
的范围#define
仅限于定义它的文件。因此,#defines
在一个源文件中创建的内容在不同的源文件中不可用。简而言之,#define
s 不尊重作用域。注意const
变量是可以作用域的。它们遵守所有作用域规则。
在编译错误期间避免奇怪的神奇数字:
如果您使用#define
的是那些在预编译时被预处理器替换所以如果您在编译期间收到错误,那将是令人困惑的,因为错误消息不会引用宏名称而是值并且它会出现一个突然的值,并且在代码中跟踪它会浪费大量时间。
易于调试:
同样出于#2中提到的相同原因,而调试#define
实际上并没有提供任何帮助。
WIDTH
是一个宏,它将被预处理器替换为值 (10),而width
是一个变量。
当您#define 宏(如此处的 WIDTH)时,预处理器将在程序传递给编译器之前简单地进行文本替换。即你WIDTH
在代码中使用的任何地方,它都会被替换为10
.
但是当你这样做时int width=10
,变量是活动的
首先是一个简短的背景:在编译之前,对C
文件进行了预处理。预处理器检查#include
和#define
语句。
在您的情况下,该#define
语句告诉预处理器使用 string 更改WIDTH
源代码中的每个字符串10
。当文件在下一步被编译WIDTH
时,实际上每次出现的都是10
. 现在,两者的区别
#define WIDTH 10
和
int width = 10;
是第一个可以看作是一个constant
值,而第二个是一个普通变量,其值可以改变。
一个#define
由预处理器处理,如果WIDTH
在源代码中找到并将其替换为10
,它所做的只是基本替换等,另一个int width = 10;
由编译器处理,这将在查找表中创建条目,生成二进制文件以在堆栈上分配足够的内存,具体取决于其定义的位置,并将值 10 复制到该内存位置。
所以一个只不过是一个常量的标签,另一个是运行时的变量。
您可以使用预处理器来加快执行速度,因为变量需要在堆栈上分配,代价是在运行时不可变。
您通常将预处理器用于不需要在运行时更改的东西,但要小心预处理器可能有点难以调试,因为它们实际上可以在源代码交给编译器之前对其进行操作,从而导致非常微妙的错误,这可能会或可能不会明显检查源代码。
定义就像一个静态的全局定义范围。它不能作为普通变量被更改或覆盖。