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() /* (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函数是否展开由编译器决定,有时候当函数太大时,编译器可能选择不展开相应的函数.

const与#define的异同的更多相关文章

  1. const与define的异同

    1. DEFINE是预处理指令,是简单的文字替换:而const是关键字,用于变量声明的修饰. 2. DEFINE替换的结果可以是数值.表达式.字符串.甚至是一个程序:而const只能限定变量为不可修改 ...

  2. 在php中定义常量时,const与define的区别?

    问]在php中定义常量时,const与define的区别?  [答]使用const使得代码简单易读,const本身就是一个语言结构,而define是一个函数.另外const在编译时要比define快很 ...

  3. 面试问题5:const 与 define 宏定义之间的区别

    问题描述:const 与 define 宏定义之间的区别 (1) 编译器处理方式不同     define宏是在预处理阶段展开:     const常量是编译运行阶段使用: (2) 类型和安全检查不同 ...

  4. 关于const和define的内存分配问题的总结

    关于const和define的内存分配问题 const与#define宏定义的区别----C语言深度剖析 1,  const定义的只读变量在程序运行过程中只有一份拷贝(因为它是全局的只读变量,存放在静 ...

  5. iOS—— static和const联合使用;使用static const 与 #define

    static和const联合使用:   static将一个全局变量变成局部变量   const将一个局部变量变成局部常量 // 定义了一个局部常量      static const CGFloat ...

  6. 实例讲述PHP面向对象的特性;;;php中const与define的使用区别

    php中const与define的使用区别 1.const:类成员变量定义,一旦定义且不能改变其值. define:定义全局常量,在任何地方都可以访问.2.define:不能在类中定义,而const可 ...

  7. const和#define常量的区别

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

  8. 【编程基础】const与#define的区别

    [前言] 相信大家看别人代码的时候都遇到过,有人用#define定义,也有人用const定义. 那么两者的区别到底是什么呢?哪个更好用呢? 网上查了又查,下面总结一下. [总结] 编译器处理方式不同 ...

  9. 函数定义从零开始学C++之从C到C++(一):const与#define、结构体对齐、函数重载name mangling、new/delete 等

    今天一直在学习函数定义之类的问题,下午正好有机会和大家共享一下. 一.bool 类型 逻辑型也称布尔型,其取值为true(逻辑真)和false(逻辑假),存储字节数在不同编译系统中可能有所不同,VC+ ...

随机推荐

  1. VueRouter和Vue生命周期(钩子函数)

    一.vue-router路由 1.介绍 vue-router是Vue的路由系统,用于定位资源的,在页面不刷新的情况下切换页面内容.类似于a标签,实际上在页面上展示出来的也是a标签,是锚点.router ...

  2. Qt如何去掉按钮等控件的虚线框(焦点框)

    方法1:可以通过代码ui->pushButton->setFocusPolicy(Qt::NoFocus)或在Qt Creator的属性列表中设置. 方法2:如果在嵌入式设备中需要通过按键 ...

  3. Insert Into select 与 Select Into 哪个更快?

    在平常数据库操作的时候,我们有时候会遇到表之间数据复制的情况,可能会用到INSERT INTO SELECT 或者 SELECT INTO : 那么二者语法上有什么区别?性能上又如何呢? 围绕着这两个 ...

  4. re 模块 分组特别说明

    关于分组优先以及 " | " 的细致练习 from django.test import TestCase import re # Create your tests here. ...

  5. vue数组中对象属性变化页面不渲染问题

    问题引入 Vue之所以能够监听Model状态的变化,是因为JavaScript语言本身提供了Proxy或者Object.observe()机制来监听对象状态的变化.但是,对于数组元素的赋值,却没有办法 ...

  6. linux usb总线驱动(一)

    目录 linux usb总线驱动框架 USB 介绍 传输类型 控制器接口 2440接口 基本流程 alloc_dev choose_address hub_port_init usb_get_devi ...

  7. MySQL5.7.23解压版安装教程

    每次找安装教程太麻烦,因此给自己备份一下步骤,方便以后查看.解压版下载地址https://dev.mysql.com/downloads/mysql/,详细图解如下: 1.根据自己需求,选择适合自己的 ...

  8. matlab中randi代替randint生成随机均匀分布信号的用法

    %%新函数  2*randi([0,1],2,1)-1   等价于老函数     2*randint(2,1)-1 函数形式:randi([imin,imax],m,n) 参数解释: [imin,im ...

  9. HDU 6108(整除判断 数学)

    题意是求在给定的 P 进制下,满足条件的数字 B 有多少.条件:若任何一个数的各位数字之和能被 B 整除,则该数可被 B 整除. 在 p 进制下,每个正整数都可以都可以表示为:a0*p^0 + a1* ...

  10. httpClient4.5 closeableHttpClient用法

    HttpClient一 简介1.尽管java.net包提供了基本通过HTTP访问资源的功能,但它没有提供全面的灵活性和其它很多应用程序需要的功能.HttpClient就是寻求弥补这项空白的组件,通过提 ...