C #定义vs常量全局

C #定义vs常量全局,c,c-preprocessor,C,C Preprocessor,执行以下操作之间有什么区别: const int var1=100; #define var2 200 int main(int argc, char* argv[]) { } var2是否占用地址/值,还是由编译器替换?在您的示例中,var2只是由C预处理器替换的文本。在编译程序之前,预处理器解析源文件并用扩展文本替换任何出现的“var2”(不在注释或字符串文本中),在您的示例中,扩展文本是数字200。它不会占用内存空间,因为编译器甚至看不到“var2”,它只看到数值常量文本“20

执行以下操作之间有什么区别:

const int var1=100;
#define   var2 200

int main(int argc, char* argv[]) 
{

}

var2
是否占用地址/值,还是由编译器替换?在您的示例中,
var2
只是由C预处理器替换的文本。在编译程序之前,预处理器解析源文件并用扩展文本替换任何出现的“var2”(不在注释或字符串文本中),在您的示例中,扩展文本是数字
200
。它不会占用内存空间,因为编译器甚至看不到“var2”,它只看到数值常量文本“200”

然而,
var1
是一个不可修改的左值(即它确实存在于内存中)。当您使用关键字
const
限定变量定义时,每当程序试图修改变量时,编译器都会抛出错误

使用像
#define var2 200这样的宏确实有性能优势-即程序占用的内存更少(因为堆栈上的变量更少),程序运行速度可能会快一点(也许可以忽略不计)(因为处理器不必总是从内存中加载值)


但是,宏可能容易出错,而且,除了在性能最为密集的应用程序中,使用
const
变量的保护措施通常会超过成本。不过,今天的编译器非常智能,可以对
const
变量执行优化,以进一步降低性能成本。

在您的示例中,
var2
只是一个文本,将由C预处理器代替。在编译程序之前,预处理器解析源文件并用扩展文本替换任何出现的“var2”(不在注释或字符串文本中),在您的示例中,扩展文本是数字
200
。它不会占用内存空间,因为编译器甚至看不到“var2”,它只看到数值常量文本“200”

然而,
var1
是一个不可修改的左值(即它确实存在于内存中)。当您使用关键字
const
限定变量定义时,每当程序试图修改变量时,编译器都会抛出错误

使用像
#define var2 200这样的宏确实有性能优势-即程序占用的内存更少(因为堆栈上的变量更少),程序运行速度可能会快一点(也许可以忽略不计)(因为处理器不必总是从内存中加载值)


但是,宏可能容易出错,而且,除了在性能最为密集的应用程序中,使用
const
变量的保护措施通常会超过成本。不过,今天的编译器非常智能,可以对
常量
变量执行优化,以进一步降低性能成本。

除非您在
var1
上使用操作符的
&
地址,否则编译器没有义务给它一个固定地址。(如果变量是用外部链接定义的,则可能会这样做。)

即使您使用
var1
s地址,编译器也有权用已知值替换对变量的引用。因此,在运行时,定义常量的两种方法之间没有真正的区别

在编译过程中,有一个区别:
var2
可以用于编译器需要常量的地方,例如大小写标签或数组大小,而
var1
不能。这对性能没有影响,但可能仍然需要考虑


此外,整数文字(如果使用的话)必须存储在某个地方,即使它是机器指令的直接操作数。这是否可行和有益取决于整数的大小和机器架构。它不取决于常量是否有名称。

除非您在
var1
上使用运算符的
&
地址,否则编译器没有义务给它一个固定地址。(如果变量是用外部链接定义的,则可能会这样做。)

即使您使用
var1
s地址,编译器也有权用已知值替换对变量的引用。因此,在运行时,定义常量的两种方法之间没有真正的区别

在编译过程中,有一个区别:
var2
可以用于编译器需要常量的地方,例如大小写标签或数组大小,而
var1
不能。这对性能没有影响,但可能仍然需要考虑


此外,整数文字(如果使用的话)必须存储在某个地方,即使它是机器指令的直接操作数。这是否可行和有益取决于整数的大小和机器架构。它不取决于常量是否有名称。

var2
在代码到达compiler@NateEldredge谢谢,这是一个有用的链接。但我并不真正理解公认的答案,例如:
const在C中并不意味着某个东西是常量。它只是意味着变量是只读的。
只读不意味着某些东西是常量吗?或者这仅仅意味着它可能不是常量,但对于这个程序来说只是只读的?@samuelbrody1249:我认为它们的意思是“常量”,即“编译时已知的值”。您可以拥有
extern const int foo
在这种情况下,编译器不知道
foo
的值,并且无论何时读取其值,都会生成内存访问,就像任何其他变量一样(禁止链接时间优化等)。如果您试图以一种明显的方式写入
foo
,编译器只会生成一个诊断。
var2
在代码到达编译之前被预处理器替换