宏常量:为了实现简单,会定义宏常量
优点:1.一改全改,2.降低出错率,3.可读性高,
缺点:在预处理阶段进行替换,不会进行类型检测,安全性低(如果写错因为在预处理阶段不会在文件定义宏处报错,而会在使用处报错);
建议:尽量使用const修饰的常量替换宏常量
宏函数:
优点:
1.不是函数,少了函数调用,提高程序运行效率,
2.少写代码:因为宏函数是多条语句的封装—注意:不能提高代码复用率,因为宏函数在预处理阶段就展开了
3.可以提高代码的可读性
缺点:
1.在预处理阶段被替换,不会进行类型检测,代码安全性低
2.在预处理阶段展开–>不能调试
3.每个使用部分都会展开---->造成代码膨胀
4.容易出错,每个部分需要加括号
5.宏函数可能会有副作用
eg:宏函数可能会有副作用
#define Max(a,b) ((a)>(b))?a:b;
int main()
{
int x = 1;
int y = 2;
int z = Max(x,y++);
//得到的z不是我们想象的3,而是四;
}
建议:使用内联函数代替宏函数–函数写法,宏的作用;
内联函数
优点:
1.因为是函数,参数有类型,会在编译阶段进行参数类型的检测,代码安全性高;
2.在Debug模式下不会展开,可以调试—也可以对编译器进行设置来验证到底是否展开
3.不用像宏函数到处加括号,实现简单
3.内联函数是函数不会产生副作用
4.代码可读性高
5.在编译阶段展开,少了调用函数的开销,可以提高程序的可读性
缺点:
每个使用内联函数的位置几乎都会展开,会造成代码膨胀
注意:
1.对于代码长或者函数体内有循环 / 递归的函数编译器优化时会自动忽略掉内联(inline);
inline int Add(int left,int right)//inline只是建议编译器在编译时展开,到底会不会展开还得看编译器;
{
int z = left + right;
return z;
}
int main()
{
int a = 1;
int b = 2;
int z = Add(a,b);
return z;
}
2.内联函数具有文件作用域—内联函数只能在定义它的文件中调用其他文件中不可以;
分析:
如果编译器将此函数当作内联函数来调用,在编译时,并不会生成真正的此函数,而是将函数展开 反汇编中并不会出现call这一步;想在不同文件中调用得有函数地址用来链接不同文件,内联函数不会调用函数(不会call)就不会生成地址,无法连接;
解决办法
宏常量用const修饰常量替换
宏函数用内联函数替换