欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

浅谈define和const的区别

程序员文章站 2024-03-23 13:38:04
...

首先,本质上两者不同,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定义的常量,只作替换,不做计算,不做表达式求解。