1、宏定义函数
原理:用宏名来表示一个函数,在宏使用时,直接将函数来取代宏名。
//如果不给x和y分别加括号,对于add(a|b,a&c)这种运算会出问题
#define add(x,y) ((x)+(y))
int main() {
int ret = add(1, 3);
return 0;
}
缺点:(1)由上面代码可知宏定义函数容易出错。
(2)不能调试,而是直接被替换。
(3)无类型安全的检查。
优点:(1)无类型的严格限制。
(2)针对频繁调用的函数无需再建立栈帧,从而提高效率。
2、内联函数
以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,不会建立函数栈帧,提升程序运行的效率。但是内联函数只适用于规模小的函数(取决于内部编译器),若函数规模大、有递归或频繁调用的函数,编译器会忽略inline的特性。另外,内联函数不建议声明和定义分离(直接在头文件中定义即可),否则在调用时会导致链接错误。
优点:inline是一种以空间换时间的做法,编译阶段会用函数。体替换函数调用,减少调用开销,提高程序运行效率。
缺点:在函数体替换后会使目标文件变大。
inline int add(int x, int y) {
return x + y;
}
int main() {
int ret = add(1, 3);
return 0;
}
3、auto的使用
auto修饰变量时,会根据该数据最终赋值的类型自动推导该变量的类型,使用auto定义变量时必须对其进行初始化,在编译阶段编译器需要根据初始化表达式来推导auto的实际类型。
auto min(int x, int y) {
return x - y;//x,y都是整型,因此auto会自动推导返回类型为整型
}
int main() {
auto ret = min(1, 3);//min返回类型为整型,因此auto会自动推导返回类型为整型
auto a = 1, b = 2;//连续定义变量时,变量类型要保持一致,否则编译器报错
return 0;
}
auto不适用的情景:(1)不能作为函数的参数。
(2)不能直接用来声明数组。
4、范围for循环的简单使用
对于一个有范围的集合而言(使用对象是范围一定的数组),如果在程序中再次说明循环的范围将是多余的,有时候还容易出现错误,而范围for循环很好解决这一问题,默认将数组中第一个元素当作循环开始,最后一个元素当作循环结束。
#include<iostream>
using std::cout;
int main() {
int arr[5] = { 1,2,3,4,5 };
for (auto e : arr)//将arr中的数据依次给e打印,这里的auto定义e,表明e的类型和arr一样
{
cout << e << " ";
}
return 0;
}