zoukankan      html  css  js  c++  java
  • const与#define的异同

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

     

  • 相关阅读:
    OpenCV (十二)阈值操作
    OpenCV (十一)图像金字塔
    OpenCV (十)提取水平线与垂直线
    OpenCV (九)形态学操作:开操作,闭操作,形态学梯度,顶帽,黑帽
    电商平台资料学习
    四、eslint配置rules
    三、export和export default区别
    二、安装国际化
    一、vue安装
    vue执行命令时提示错误——vue : 无法加载文件 C:UsersAdministratorAppDataRoaming pmvue.ps1,因为在此系统上禁止运行脚本
  • 原文地址:https://www.cnblogs.com/fengkang1008/p/4746157.html
Copyright © 2011-2022 走看看