user-0 提问: C语言const的这个优点怎么解释？

回复:
user: user-1
content: double I=PI; file://编/译期间进行宏替换，分配内存               （//宏替换，，为啥分配内存？） double J=PI; file://再/进行宏替换，又一次分配内存！ 书上是不是弄错了，本义是不是给I，J分配内存，宏在预处理的时候直接替换为值了，在编译开始的时候已经是下边这样了 double I=3.14159 ;  double J=3.14159 ;   另外，在C中，const变量是外部链接的，最起码要分配一次内存，所以它的说法应该是正确的。 在C++中，简单的const变量定义，也是不分配内存的，进行了常量折叠，只是放在了符合表中。 所以在C++中， const int a=10； int array[a]; 的写法是没问题的，在C中就不行。 除非在C++中，使用了extern 申明或者程序中有引用了const变量的地址，这个时候就会分配内存。

user: user-2
content: #define是一个真常量，而const却是由编译器判断实现的常量，是一个假常量。在实际中，使用const定义的变量，最终还是一个变量，只是在编译器内进行了检查，发现有修改则报错。

user: user-3
content: “用const可以节省空间，避免不必要的内存分配”。这句话我还是第一次听说哦。 const使用户告诉编译器限制变量不可以被修改，若被修改则给出错误提示。注意，不是说const定义的变量是常量哦。

user: user-4
content: #include<stdio.h>  #define M 12 const int N = 33;  int main() { 	int a = M; 	int b = N; 	int c = M; 	 	return 0; }   汇编之后的代码是：  	.globl	_N 	.section .rdata,"dr" 	.align 4 _N: 	.long	33 	.def	___main;	.scl	2;	.type	32;	.endef 	.text 	.globl	_main 	.def	_main;	.scl	2;	.type	32;	.endef _main: LFB6: 	.cfi_startproc 	pushl	%ebp 	.cfi_def_cfa_offset 8 	.cfi_offset 5, -8 	movl	%esp, %ebp 	.cfi_def_cfa_register 5 	andl	$-16, %esp 	subl	$16, %esp 	call	___main 	movl	$12, 12(%esp) 	movl	_N, %eax 	movl	%eax, 8(%esp) 	movl	$12, 4(%esp) 	movl	$0, %eax 	leave 	.cfi_restore 5 	.cfi_def_cfa 4, 4 	ret 	.cfi_endproc LFE6:  从代码看来宏替换确实是不占用内存的，被当作立即数来处理了。

user: user-5
content: 防止修改，有些参数需要这种类型

user: user-6
content: 引用 8 楼 zhaocanxing 的回复:[quote=引用 6 楼 Adol1111 的回复:] [quote=引用 5 楼 zhaocanxing 的回复:] [quote=引用 4 楼 lgf2002 的回复:] double I=PI; file://编/译期间进行宏替换，分配内存               （//宏替换，，为啥分配内存？） double J=PI; file://再/进行宏替换，又一次分配内存！ 书上是不是弄错了，本义是不是给I，J分配内存，宏在预处理的时候直接替换为值了，在编译开始的时候已经是下边这样了 double I=3.14159 ;  double J=3.14159 ;   另外，在C中，const变量是外部链接的，最起码要分配一次内存，所以它的说法应该是正确的。 在C++中，简单的const变量定义，也是不分配内存的，进行了常量折叠，只是放在了符合表中。 所以在C++中， const int a=10； int array[a]; 的写法是没问题的，在C中就不行。 除非在C++中，使用了extern 申明或者程序中有引用了const变量的地址，这个时候就会分配内存。 如果PI是宏定义的，预编译就替换为了3.14159， 但是3.14159也是一个常量，本身就是要占用内存空间的，调用了几次宏就要分配几次空间。如果PI是const变量，那么他只有一个地址空间，不会重复的分配。[/quote] 立即数的地址在CPU上（寄存器地址），不是内存地址哦。不过重复生成立即数也不是什么好事，不如先生成一个数，然后替换需要的内容，这一点上就不如const了。不过对于预处理的过程我也不太了解，是否会重复用生成立即数也不一定。[/quote] 你说的立即数是汇编里面的吧（比如：mov ax 1 这本身就是一条指令，常量是指令的一部分），C中没有立即数只有常量吧，常量在内存的常量存储区里面的[/quote] C语言中字面值常量就是立即数,你看看汇编码就知道了。C语言常量区是指文字常量区，存字符串的，就是char* p="hello"; const常量只不过是被修饰的只读变量，概念不一样。

user: user-4
content: 引用 6 楼 Adol1111 的回复:[quote=引用 5 楼 zhaocanxing 的回复:] [quote=引用 4 楼 lgf2002 的回复:] double I=PI; file://编/译期间进行宏替换，分配内存               （//宏替换，，为啥分配内存？） double J=PI; file://再/进行宏替换，又一次分配内存！ 书上是不是弄错了，本义是不是给I，J分配内存，宏在预处理的时候直接替换为值了，在编译开始的时候已经是下边这样了 double I=3.14159 ;  double J=3.14159 ;   另外，在C中，const变量是外部链接的，最起码要分配一次内存，所以它的说法应该是正确的。 在C++中，简单的const变量定义，也是不分配内存的，进行了常量折叠，只是放在了符合表中。 所以在C++中， const int a=10； int array[a]; 的写法是没问题的，在C中就不行。 除非在C++中，使用了extern 申明或者程序中有引用了const变量的地址，这个时候就会分配内存。 如果PI是宏定义的，预编译就替换为了3.14159， 但是3.14159也是一个常量，本身就是要占用内存空间的，调用了几次宏就要分配几次空间。如果PI是const变量，那么他只有一个地址空间，不会重复的分配。[/quote] 立即数的地址在CPU上（寄存器地址），不是内存地址哦。不过重复生成立即数也不是什么好事，不如先生成一个数，然后替换需要的内容，这一点上就不如const了。不过对于预处理的过程我也不太了解，是否会重复用生成立即数也不一定。[/quote] 你说的立即数是汇编里面的吧（比如：mov ax 1 这本身就是一条指令，常量是指令的一部分），C中没有立即数只有常量吧，常量在内存的常量存储区里面的

user: user-6
content: 我刚刚查了下例子：#define M  3//宏常量 const int N=5;//此时并未将N放入内存中 ......  int i=N;//此时为N分配内存，以后不再分配 int I=M;//预编译期间进行宏替换，分配内存  int j=N;//没有分配内存 int J=M;//再进行宏替换，又一次分配内存我觉得这样说不对，N的确只生成了一次内存，但i、j也会生成相应的内存地址，这样就是3个内存地址了。  但是宏是不一样的，M从来就没有生成内存，替换时是一个立即数，立即数本身就不占内存。除非这个预处理有问题，是生成一个M变量，然后再赋值，这根本和预处理的解释不同！！！那么分配的内存的只有I、J，也就是2个内存地址。还比const少一个。  我觉得例子举的不太好，宏本身是不占内存的，占内存的是宏替换以后的代码是否占内存。就这一点来说是很有问题的，感觉《C语言深度解剖》这本书解释得有点问题。

user: user-6
content: 引用 5 楼 zhaocanxing 的回复:[quote=引用 4 楼 lgf2002 的回复:] double I=PI; file://编/译期间进行宏替换，分配内存               （//宏替换，，为啥分配内存？） double J=PI; file://再/进行宏替换，又一次分配内存！ 书上是不是弄错了，本义是不是给I，J分配内存，宏在预处理的时候直接替换为值了，在编译开始的时候已经是下边这样了 double I=3.14159 ;  double J=3.14159 ;   另外，在C中，const变量是外部链接的，最起码要分配一次内存，所以它的说法应该是正确的。 在C++中，简单的const变量定义，也是不分配内存的，进行了常量折叠，只是放在了符合表中。 所以在C++中， const int a=10； int array[a]; 的写法是没问题的，在C中就不行。 除非在C++中，使用了extern 申明或者程序中有引用了const变量的地址，这个时候就会分配内存。 如果PI是宏定义的，预编译就替换为了3.14159， 但是3.14159也是一个常量，本身就是要占用内存空间的，调用了几次宏就要分配几次空间。如果PI是const变量，那么他只有一个地址空间，不会重复的分配。[/quote] 立即数的地址在CPU上（寄存器地址），不是内存地址哦。不过重复生成立即数也不是什么好事，不如先生成一个数，然后替换需要的内容，这一点上就不如const了。不过对于预处理的过程我也不太了解，是否会重复用生成立即数也不一定。

user: user-4
content: 引用 4 楼 lgf2002 的回复:double I=PI; file://编/译期间进行宏替换，分配内存               （//宏替换，，为啥分配内存？） double J=PI; file://再/进行宏替换，又一次分配内存！ 书上是不是弄错了，本义是不是给I，J分配内存，宏在预处理的时候直接替换为值了，在编译开始的时候已经是下边这样了 double I=3.14159 ;  double J=3.14159 ;   另外，在C中，const变量是外部链接的，最起码要分配一次内存，所以它的说法应该是正确的。 在C++中，简单的const变量定义，也是不分配内存的，进行了常量折叠，只是放在了符合表中。 所以在C++中， const int a=10； int array[a]; 的写法是没问题的，在C中就不行。 除非在C++中，使用了extern 申明或者程序中有引用了const变量的地址，这个时候就会分配内存。 如果PI是宏定义的，预编译就替换为了3.14159， 但是3.14159也是一个常量，本身就是要占用内存空间的，调用了几次宏就要分配几次空间。如果PI是const变量，那么他只有一个地址空间，不会重复的分配。

user: user-7
content: 在MCU中，const常量会放在程序存储区，不会存在动态区。所以从这角度来看，楼主的说话节省空间就是指的动态区，也就是堆中。

user: user-0
content: 我这边反汇编看了下，编译器把他们全都变成立即数了，这样感觉const和define在效率上就更没区别了！

user: user-8
content: #define是宏，编译时替换， const 在 c 中 == read only, 仍是 变量

user: user-9
content: 在《C语言深度解剖》书上也有看到这么解释的，具体原理不是很清楚