1  作为常量时的异同

(0)  相同

两者都可以用来定义常量;

#define PI 3.14159 // 常量宏  
      const doulbe Pi=3.14159; // 常量

(1)  编译器处理方式不同

  define宏是在预处理阶段展开;

  const常量是编译运行阶段使用;

(2)  类型和安全检查不同

  define宏没有类型,不做任何类型检查,仅仅是展开。

  const常量有具体的类型,在编译阶段会执行类型检查。

(3)  存储方式不同

  define宏在定义时不会分配内存;define宏仅仅是展开,有多少地方使用,就展开多少次;

  const常量在定义时会在内存中分配(可以是堆中也可以是栈中);

(4)  赋值时的空间分配

   const  可以节省空间,避免不必要的内存分配。 例如:  
        #define PI 3.14159 //常量宏  
        const doulbe Pi=3.14159; //此时并未将Pi放入ROM中 ......  
        double i=Pi; //此时为Pi分配内存,以后不再分配!  
        double I=PI; //编译期间进行宏替换,分配内存  
        double j=Pi; //没有内存分配  
        double J=PI; //再进行宏替换,又一次分配内存!  
        const定义常量从汇编的角度来看,只是给出了对应的内存地址,而不是象#define一样给出的是立即数,所以,const定义的常量在程序运行过程中只有一份拷贝,而 #define定义的常量在内存中有若干个拷贝。 

(5)  提高了效率

编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高。

2 C++中二者的比较

C++ 语言可以用const来定义常量,也可以用 #define来定义常量。但是前者比后者有更多的优点:

(1)const常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查。而对后者只进行字符替换,没有类型安全检查,并且在字符替换可能会产生意料不到的错误(边际效应)。

(2)有些集成化的调试工具可以对const常量进行调试,但是不能对宏常量进行调试。

【规则5-2-1】在C++ 程序中只使用const常量而不使用宏常量,即const常量完全取代宏常量。

【规则5-3-1】需要对外公开的常量放在头文件中,不需要对外公开的常量放在定义文件的头部。为便于管理,可以把不同模块的常量集中存放在一个公共的头文件中。

【规则5-3-2】如果某一常量与其它常量密切相关,应在定义中包含这种关系,而不应给出一些孤立的值。例如:

        const  float   RADIUS = 100;

const  float   DIAMETER = RADIUS * 2;

2  #define其他功能

2.1  简单宏定义

  #define MAXTIME 1000; // 功能类似const常量

2.2  带参宏定义

  define可以像函数那样接受一些参数,如下:

  #define max(x,y) (x)>(y)?(x):(y);

  它将返回两个数中较大的那个,这个“函数”没有类型检查,就好像一个函数模板似的,当然,不难看出它绝对没有模板那么安全。

2.3  多行宏定义

  define可以替代多行的代码,例如MFC中的宏定义(非常的经典,虽然让人看了恶心):

#define MACRO(arg1, arg2) do { //* declarations */ /stmt1; /stmt2; //*  */ /} while(0) /* (no trailing ; ) */

  关键是要在每一个换行的时候加上一个"/"。

2.4  条件编译

  在大规模的开发过程中,特别是跨平台和系统的软件里,define最重要的功能是条件编译。  

#ifdef  WINDOWS
// do something
#endif
#ifdef    LINUX
// do something
#endif#ifdef  DV22_AUX_INPUT
#define  AUX_MODE 3
#else
#define  AUY_MODE 3
#endif

  可以在编译的时候通过#define设置编译环境

3  const其他功能

  常类型是指使用类型修饰符const说明的类型,常类型的变量或对象的值是不能被更新的。

4   inline

1) 产生背景
inline这个关键字的引入原因和const十分相似,inline 关键字用来定义一个类的内联函数,引入它的主要原因是用它替代C中表达式形式的宏定义。
表达式形式的宏定义一例:
   #define ExpressionName(Var1,Var2) (Var1+Var2)*(Var1-Var2)
       这种表达式形式宏形式与作用跟函数类似,但它使用预编译器,没有堆栈,使用上比函数高效。但它只是预编译器上符号表的简单替换,不能进行参数有效性检测及使用C++类的成员访问控制。
inline 推出的目的,也正是为了取代这种表达式形式的宏定义,它消除了它的缺点,同时又很好地继承了它的优点。inline代码放入预编译器符号表中,高效;它是个真正的函数,调用时有严格的参数检测;它也可作为类的成员函数。
2) 具体作用
直接在class类定义中定义各函数成员,系统将他们作为内联函数处理;成员函数是内联函数,意味着:每个对象都有该函数一份独立的拷贝。
在类外,如果使用关键字inline定义函数成员,则系统也会作为内联函数处理;

1:宏define在预处理阶段完成;inline在编译阶段
2:类型安全检查
inline函数是函数,要做类型检查;宏定义则不用
3:替换方式
define字符串替换;inline是指嵌入代码,在编译过程中不单独产生代码,在调用函数的地方不是跳转,而是把代码直接写到那里去,对于短小的函数比较实用,且安全可靠。
4:inline函数是否展开由编译器决定,有时候当函数太大时,编译器可能选择不展开相应的函数.

转载于:https://www.cnblogs.com/fengkang1008/p/4746157.html

const与#define的异同相关推荐

  1. C++ const与define

    昨日面试被组考官问及const与define异同,开始还简单,后来被问的我脑袋是一团浆糊.今日差点资料总结一下 1. const与define. 两者都可以用来定义常量,但是const定义时,定义了常 ...

  2. const与define相比优点_const与#define的区别、优点

    const与#define的区别 编译器处理方式不同 define宏是在预处理阶段展开. 补充:预处理器根据以#开头的命令,修改原始的程序.比如我们常见的#include 命令告诉处理器读取系统头文件 ...

  3. C++编程进阶1(对于单纯的常量,用const替换#define、operator[]与const)

    一.对于单纯的常量,用const替换#define:用内联函数替换宏函数 如果想表示一个常量,请使用const而不是#define,因为#define在预编译期被简单的替换,没有类型检查.而const ...

  4. const 和 #define区别

    1) 编译器处理方式不同 define宏是在预处理阶段展开. const常量是编译运行阶段使用. (2) 类型和安全检查不同 define宏没有类型,不做任何类型检查,仅仅是展开. const常量有具 ...

  5. C++ 中 const和define的区别

    来源网址:http://wujiangping.blog.163.com/blog/static/195182011201255115125205/ 请区别用#define命令定义的符号常量和用con ...

  6. php中const和define,PHP中const和define的区别是什么

    PHP中const和define的区别是什么 发布时间:2020-09-10 10:14:36 来源:亿速云 阅读:65 作者:小新 PHP中const和define的区别是什么?这个问题可能是我们日 ...

  7. 详解const和#define

    目录 一.const 与 #define的区别 二.常量定义规则 三.类中的常量 一.const 与 #define的区别 (1) 编译器处理方式不同 define宏是在预处理阶段展开. const常 ...

  8. C和指针之const、#define、volatile

    1.const   定义const 只读变量,具有不可变形 const int a = 100; 编译器通常不为普通Const只读变量分配存储空间, 而是将它们保存在符号表中,   这使得它成为一个编 ...

  9. C语言 const 和 define 区别 - C语言零基础入门教程

    目录 一.const 使用 1.const 修饰变量 2.const 修饰指针 3.const 修饰在函数名前面 4.const 修饰在函数名后面 5.const 修饰函数参数 二.define 使用 ...

最新文章

  1. 步进或伺服运动控制偏位问题:现象、原因及解决办法
  2. [转] 数学符号英文拼写及发音
  3. 服务器不能自动备份软件,windows服务器自动备份上传软件+bat
  4. 机器学习/梯度下降算法
  5. 数学教育中的AI:NeurIPS’21 Workshop 欢迎投稿!
  6. 二叉树的遍历实验报告C语言,二叉树的建立与遍历实验报告(c语言编写,附源代码)...
  7. Convert.ToString和ToString的区别
  8. Linux centos7安装RabbitMQ3.8.9
  9. Redis的持久化——AOF
  10. python 计算两个经纬度的距离_使用经纬度和海拔(高程)计算两点之间的距离...
  11. hadoop完全分布式搭建以及试运行
  12. 【分享】品牌平面广告创意过程与思维技巧
  13. 已解决:网易邮箱smtphz.qiye.163.com在阿里云环境发不出邮件的问题
  14. 重装系统win7教程
  15. nc服务器修改过ip地址,nc服务器修改过ip地址
  16. python如何爬虫股票数据_python爬虫实例,股票数据定向爬虫
  17. 小松鼠邮件(squirrelmail)服务器部署(squirrelmail+Postfix)
  18. 201671030125 曾佳+《英文文本统计分析》结对项目报告
  19. Google安全浏览算法更新:屡教不改的站点将被屏蔽30天
  20. veloview读二维雷达数据_【SLAM】之Velodyne VLP16 激光雷达使用

热门文章

  1. 实践自定义UI—View
  2. JSP 第一天:提交表单--获取表单中的数据值
  3. php中对MYSQL操作之事务控制,回滚
  4. easyNeurons 神经网络入门教程
  5. tcp/ip详解--封装
  6. python二十四:python练习题
  7. 长春理工大学第十四届程序设计竞赛(重现赛)M.Orx Zone
  8. 3.4. Wireless Networking
  9. 高可用flume-ng搭建
  10. 在 Android Studio 2.2 中愉快地使用 C/C++