宏缺陷一:必须要加括号保证运算完整
#define MYADD(x,y) ((x) +(y))//宏加法加了括号就可以保证运算完整。
void test01()
{
int a = 10;
int b = 20;
int ret = MYADD(a, b) * 20;
//结果是410,因为在宏展开的时候y和20先相乘然后再加上前面的10。
cout << ret << endl;
}
宏缺陷二:即使加了括号,有些运算依然与预期不符
#define MYCOMPARE(a,b) (((a) < (b)) ? (a) : (b))
//三目运算符
void myCompare(int a, int b)
{
int ret = a < b ? a : b;
cout << "ret = " << ret << endl;//结果为11,普通函数不会出现与预期结果不同的问题。
}
void test02()
{
int a = 10;
int b = 20;
myCompare(++a, b);
//int ret = MYCOMPARE(++a, b); //预期结果11,结果变为12 (((++a) < (b)) ? (++a) : (b))
//相当于a做了两次前置++
//cout << "ret = " << ret << endl;
}
内联函数
本身也是一个真正的函数,具有普通函数的所有行为,内联函数会在适当的地方像预定义宏一样展开(不会入栈和出栈,不需要调用函数开销。)
函数的声明和实现必须同时加inline关键词才算内联函数,当内联函数实现
内联函数的好处,解决宏缺陷,本身是一个函数,带来宏优势,以空间换时间,带来函数展开
inline void func();
inline void func(){};
类内部的成员函数在函数前都隐式地加了inline
内联函数的限制
- 不能存在任何形式的循环语句
- 不能存在过多的条件判断语句
- 函数体不能过于庞大
- 不能对函数进行取址操作
以上可能不会按照内联函数处理
内联函数没有地址
总结:
内联函数仅仅是给编译器的一个建议,编译器不一定会接受这种建议。
好的内联函数会给短小的函数加编译器inline.
如果你没有将函数声明为内联函数,编译器也可能将此函数做内联编译。
建议自己别加了