一、程序及输出
1.1 宏缺陷1 : 必须要加括号保证运算完整
不加括号:
#include<iostream>
using namespace std;
#define MYADD(x,y) x +y
void test01()
{
int a = 10;
int b = 20;
int ret = MYADD(a, b) * 2;
cout << ret << endl;
}
int main(){
test01();
system("pause");
return EXIT_SUCCESS;
}
输出:
加括号:
#include<iostream>
using namespace std;
#define MYADD(x,y) ((x) +(y))
void test01()
{
int a = 10;
int b = 20;
int ret = MYADD(a, b) * 2;
cout << ret << endl;
}
int main(){
test01();
system("pause");
return EXIT_SUCCESS;
}
输出:
1.2 宏缺陷2:即使加了括号,有些运算依然与预期不符
#include<iostream>
using namespace std;
#define MYCOMPARE(a,b) (((a) < (b)) ? (a) : (b))
void test02()
{
int a = 10;
int b = 20;
int ret = MYCOMPARE(++a, b); //预期是 11 结果变为12 (((++a) < (b)) ? (++a) : (b))
cout << "ret = " << ret << endl;
}
int main(){
test02();
system("pause");
return EXIT_SUCCESS;
}
输出:
运行了两次自加运算符
1.3 内联函数
内联函数
函数的声明和实现必须同时加关键字 inline 才算内联函数
inline void func();
inline void func(){};
内联函数 好处 :解决宏缺陷,本身是一个函数,带来宏优势,以空间换时间,在适当的时候做展开
类内部的成员函数 在函数前都隐式加了关键字 inline
有些情况下,写了关键字inline也不会按照内联方式处理
出现循环
出现判断
函数体过于庞大
对函数进行取地址
总结:内联函数只是给编译器一个建议,但是编译器不一定接受这个建议,好的编译器会自己给短小的函数前加上关键字inline
1.4 内联函数和宏
内联函数和宏在某种程度上都可以用来进行代码的替换,但它们有一些重要的区别和关联的缺陷:
内联函数:
内联函数是由编译器处理的,它提供了类型安全性和函数特性,可以进行参数检查和返回值检查。
内联函数的缺陷在于,如果函数体过大或者包含循环等复杂结构,编译器可能不会将其作为内联函数,从而失去了内联的优势。
宏:
宏:
宏是在预处理阶段进行简单的文本替换,不进行参数检查和返回值检查,也不考虑代码的类型安全性。
宏的缺陷在于,由于它只是简单的文本替换,可能会导致一些意想不到的问题,例如参数多次计算、缺乏类型检查等。
内联函数和宏都可以用来进行代码替换,但内联函数提供了更多的类型安全性和函数特性,而宏则更加灵活,但容易引发一些潜在的问题。在实际编程中,应该根据具体的情况选择合适的方式来进行代码替换。
二、分析与总结
- 宏缺陷1 :
必须要加括号保证运算完整
- 宏缺陷2:
即使加了括号,有些运算依然与预期不符
- 内联函数:
解决宏缺陷,但仍有自己的局限性