菜鸟笔记
提升您的技术认知

define与typedef、const、inline的区别

define与typedef区别

  define是宏定义,typedef是重命名。

typedef int int_32;
typedef void(*Func)(int);  // Func为一个函数指针
#define PI 3.1415   // 宏定义没有;
#define max(x,y) ((x)>(y)?(x):(y)) 
作用域不同
  • typedef

(1)如果放在所有函数之外,它的作用域就是从它定义开始直到文件尾;

(2)如果放在某个函数内,定义域就是从定义开始直到该函数结尾;

  • #define

(1)不管是在某个函数内,还是在所有函数之外,作用域都是从定义开始直到整个文件结尾。

(2)在同一编译单元内部,就算在不同的命名空间内,其作用范围不变。也就是从定义处一直到文件结束。

define与const的区别

(1)宏没有类型检查,只是字符的替换,而且可能由于边际效应在字符替换时产生意料不到的错误;const常量有严格的类型检查

(2)宏常量不开辟内存空间,const常量开辟内存空间

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

(4)c++中const完全取代宏

#define ASPECT_RATIO 1.653    (#define宏后面没有分号;)

  记号名称ASPECT_RATIO也许从未被编译器看见,也许在编译器开始处理源码之前它就被预处理器移走了。于是ASPECT_RATIO可能没有进入记号表。于是当你运用此常量但获得一个编译错误时,这个错误信息会提到1.653而不是ASPECT_RATIO。如果ASPECT_RATIO被定义在一个非你所写的头文件内,则对1.653以及它来自何处毫无概念。

define和inline的区别

(1)内联函数同宏函数一样将在被调用处进行代码展开,省去了参数压栈、栈帧开辟与回收,结果返回等,从而提高程序运行速度。但是内联函数在编译时展开,而宏是由预处理器对宏进行展开

(2)内联函数会检查参数类型,运行可调试,宏定义不检查函数参数 ,运行不可调试,所以内联函数更安全。

(3)宏不是函数,而inline函数是函数

(4)宏在定义时要小心处理宏参数,(一般情况是把参数用括弧括起来)。

(5)但是内联是以代码膨胀(复制)为代价,消耗内存。

(6)构造函数/析构函数可以是内联的,但是没必要

(7)自定义宏时要注意不要和预定义宏重名,否则未定义。

#define CALL_WITH_MAX(a,b) f((a) > (b) ? (a) : (b))

  写宏函数时,必须要为宏中所有实参加上小括号,但是即使加上下括号也会遇到不可思议的事情:

int a = 5, b = 0;
CALL_WITH_MAX(++a, b);    // a被累加二次
CALL_WITH_MAX(++a, b+10)  // a被累加一次

define #和##

  define语句中的#是把参数字符串化,##是连接两个参数成为一个整体。

#define STR(s)  #s  
#define CONS(a,b) (int)(a##e##b)     
int main() {
      
    cout << (STR(vck)) << endl;    
    cout << CONS(2, 3) << endl;    
}  

CONS(2, 3)实际表示就是整型值2e3,也就是十进制数2000。