浅谈define和const的区别
首先,本质上两者不同,define修饰出来的是常量!并且是真常量!
而const修饰的是假常量,它本质还是变量!只不过编译器不让你修改!
为什么说define修饰出来的是真常量呢?因为,define是宏定义,是宏替换,意味着程序在编译前期会进行文本替换,例如代码define PI 3.1415926 这句话,编译器会将代码中所有出现PI的地方全部用3.1415926替换,然后在进行编译,所以本质它就是一个常量!
至于const,const一般修饰于定义变量的前面,比如cosnt int a = 10,意味着a就一直是19,是一个不可修改的变量了。
往后试图给a重新赋值都会引发错误。这就是const修饰之后的结果,但请注意,这里不可修改的原因其实是编译器在做检查,检查是否有修改这块内存上的值,一旦有就会报错,所以从根本上说,cosnt修饰的变量依然是一个变量!只不过编译器不让你修改而已!
- 用#define MAX 255定义的常量是没有类型的,所给出的是一个立即数,编译器只是把所定义的常量值与所定义的常量的名字联系起来,define所定义的宏变量在预处理的时候进行替换,在程序中使用到该常量的地方都要进行拷贝替换;
- 用const float MAX = 255; 定义的常量有类型名字,存放在内存的静态区域中,在程序运行过程中const变量只有一个拷贝,而#define 所定义的宏变量却有多个拷贝,所以宏定义在程序运行过程中所消耗的内存要比const变量的大得多;
- 用define可以定义一些简单的函数,const是不可以定义函数的.
- 用define定义的常量是不可以用指针变量去指向的,用const定义的常量是可以用指针去指向该常量的地址的;
const修饰指针时的使用注意事项:
const int *p; //p可变,p指向的对象不可变
int const*p; //p可变,p指向的对象不可变
int *const p; //p不可变,p指向的对象可变
const int *const p; //指针p和p指向的对象都不可变
具体区别:
1、编译器处理方式不同
define – 在预处理阶段进行替换
const – 在编译时确定其值
define是宏定义,程序在预处理阶段将用define定义的内容进行替换,因此程序运行时常量表中并没有用define定义的常量,系统不为其分配内存。
const常量是编译运行时的常量,系统为其分配内存。
2、类型与安全检查不同
define – 无类型,不进行类型安全检查,可能会产生意想不到的错误(边际效应)
const – 有数据类型,编译时会进行类型检查
define注意“边际效应”。
例:
#define N 2+3 //N的值是5
int a = N/2, //在编译时预想a=2.5,实际打印结果是3.5
原因是在预处理阶段,编译器将a=N/2处理成a=2+3/2,这就是define宏的边际效应;
所以我们应该写成#define N (2+3)
3、存储方式不同
define – 不分配内存,给出的是立即数,有多少次使用就进行多少次替换,在内存中会有多个拷贝,消耗内存大
const – 在静态存储区中分配空间,在程序运行过程中内存中只有一个拷贝,const可以节省空间,避免不必要的的内存分配
4、其他
在编译时, 编译器通常不为const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高。
define是宏定义,程序在预处理阶段将用define定义的内容进行替换,因此程序运行时常量表中并没有用define定义的常量,只作替换,不做计算,不做表达式求解。
上一篇: Hibernate从入门到精通
下一篇: 审计小trick结合