什么是宏?
- 宏定义又称为宏代换、宏替换,简称“宏”。是C提供的三种预处理功能的其中一种。
宏定义分类
1. 不带参数的宏定义:
- 格式: #define 标识符 字符串
- 其中的标识符就是所谓的符号常量,也称为“宏名”。预处理(预编译)工作也叫做宏展开:将宏名替换为字符串。
例: #define PI 3.1415926 把程序中出现的PI全部换成3.1415926
2. 带参数的宏定义(宏函数):
- 除了一般的字符串替换,还要做参数代换
- 格式: #define 宏名(参数表) 字符串
例:#define S(a,b) a*b mul=S(3,2);第一步被换为mul=a*b; 第二步被换为mul=3*2;类似于函数调用:
注意:
实参如果是表达式容易出问题
例:#define S(r) r*r
mul=S(a+b);第一步换为mul=r*r;,第二步被换为mul=a+b*a+b;这样就不满足我们的本意了,正确的宏定义是#define S(r) ((r)*(r))宏名和参数的括号间不能有空格
- 宏替换只作替换,不做计算,不做表达式求解
- 函数调用在编译后程序运行时进行,并且分配内存。宏替换在编译前进行,不分配内存
- 宏替换不存在类型,也没有类型转换。
- 函数只有一个返回值,利用宏则可以设法得到多个值
- 宏展开使源程序变长,函数调用不会
- 展开不占运行时间,只占编译时间,函数调用占运行时间(分配内存、保留现场、值传递、返回值)
宏的优缺点
1.优点:
- 提高程序运行速度
- 提高代码可读性
2.缺点:
- 不会进行类型检测,程序不安全
- 造成代码膨胀问题(代码量大大增加)
- 有副作用(++/–)
- 不能调试
什么是内联函数?
- 以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数压栈的开销,内联函数提升程序运行的效率
内联函数特性
- inline是一种以空间换时间的做法,省去调用函数额开销。所以代码很长或者有循环/递归的的函数不适宜使用内联
- inline对于编译器而言只是一个建议,编译器会自动优化,如果定义为inline的函数体内有循环/递归等等,编译器优化时会忽略掉内联
- inline必须函数定义放在一起,才能成为内联函数,仅将inline放在声明前是不起作用的
定义在类内的成员函数默认定义为内联函数
内联函数与宏函数的区别与联系
- 他们都可以提高代码运行速度
- 内联函数在编译时展开,宏在预编译时展开;
- 内联函数直接嵌入到目标代码中,宏是简单的做文本替换;
- 内联函数有类型检测、语法判断等功能,而宏没有;
- inline函数是函数,宏不是;所以内联函数可以调试,宏不能调试;
- 宏不能访问对象的私有成员,但是定义在类内的内联函数可以访问;
- 宏定义时要注意书写(参数要括起来)否则容易出现歧义,内联函数不会产生歧义;