内联函数
编译过程的最终产品是可执行程序——由一组机器语言指令组成。 运行程序时,操作系统将这些指令载入到计算机内存中,因此每条指令都有特定的内存地址。计算机随后将逐步执行这些指令。有时(如有循环或分支语句时),将跳过一些指令,向前或向后跳到特定地址。常规函数调用也使程序跳到另一个地址(函数的地址),并在函数结束时返回
执行到函数调用指令时, 程序将在函数调用后立即存储该指令的内存地址,并将函数参数复制到 堆栈(为此保留的内存块),跳到标记函数起点的内存单元,执行函数代码(也许还需将返回值放入到寄存器中),然后跳回到地址被保存的指令处。来回跳跃并记录跳跃位置意味着以前使用函数时,需要一定的开销。
对于内联代码,程序无需跳到另一个位置处执行代码,再跳回来。所以内联函数的运行速度比常规函数稍快,但代价是需要占用更多内存
要使用内联函数,需要采取以下措施
- 在函数声明前加上关键字
inline
- 在函数定义前加上关键字
inline
1 2 3 4 5 6
| inline double square(int x) { return x * x; }
cout << square(2) << endl;
|
引用变量
引用是已定义的变量的别名(另一个名称)
1 2 3 4 5 6 7 8 9 10 11
| int rats = 100; int nums = 10; int & rats_back = rats;
cout << rats << " " << rats_back << endl; rats = 101; cout << rats << " " << rats_back << endl; rats_back = nums; cout << rats << " " << rats_back << " " << nums << endl; nums = 1; cout << rats << " " << rats_back << " " << nums << endl;
|
运行结果
1 2 3 4
| 100 100 101 101 10 10 10 10 10 1
|
使用 int & rats_back = rats;
声明引用变量,即指向 int 变量的引用
- 必须在声明引用变量时进行初始化
- 一旦与某个变量关联起来,就将一直效忠于它
引用经常被用作函数参数,使得函数中的变量名成为调用程序中的变量的别名。这种传递参数的方法称为按引用传递。按引用传递允许被调用的函数能够访问调用函数中的变量。C++新增的这项特性是对C语言的超越,C语言只能按值传递
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| void swapr(int & a, int & b) { int temp; temp = a; a = b; b = temp; }
void swapp(int * p, int * q) { int temp; temp = *p; *p = *q; *q = temp; }
void swapv(int a, int b) { int temp; temp = a; a = b; b = temp; }
int wallet1 = 300; int wallet2 = 350; swapr(wallet1, wallet2); cout << wallet1 << " " << wallet2 << endl; swapp(&wallet1, &wallet2); cout << wallet1 << " " << wallet2 << endl; swapv(wallet1, wallet2); cout << wallet1 << " " << wallet2 << endl;
|
运行结果
swapp
在函数使用p和q的整个过程中使用解除 引用运算符*,所以跟 swapv
效果一样
这就是需要注意的地方,通过引用传递可能修改源值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| double cube(double a) { a = a * a; return a; }
double refcube(double &ra) { ra = ra * ra; return ra; }
double a = 2; re cout << cube(a) << " " << a << endl; cout << refcube(a) << " " << a << endl; refcube(a + 0.5);
|
可以通过 const 不允许函数修改
1
| double refcube(const double &ra);
|
所以,将引用参数声明为常量数据的引用的理由有三个:
- 使用const可以避免无意中修改数据的编程错误;
- 使用const使函数能够处理const和非const实参,否则将只能接受非const数据;
- 使用const引用使函数能够正确生成并使用临时变量。
结构体的引用变量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| struct student { string name; int age; double weight; };
void Add(student & t) { t.name = "hello"; }
student Change(student t) { t.name = "nihao"; return t; }
student t = student{ "world", 18, 77.5 }; Add(t); cout << t.name << " " << t.age << " " << t.weight << endl;
student t1 = Change(t); cout << t.name << " " << t.age << " " << t.weight << endl; cout << t1.name << " " << t1.age << " " << t1.weight << endl;
|
运行结果
1 2 3
| hello 18 77.5 hello 18 77.5 nihao 18 77.5
|
什么时候使用引用
- 如果数据对象很小,如内置数据类型或小型结构,则按值传递。
- 如果数据对象是数组,则使用指针,因为这是唯一的选择,并将指针声明为指向const的指针。
- 如果数据对象是较大的结构,则使用const指针或const引用,以提高程序的效率。这样可以节省复制结构所需的时间和空间。
- 如果数据对象是类对象,则使用const引用。类设计的语义常常要求使用引用,这是C++新增这项特性的主要原因。因此,传递类对象 参数的标准方式是按引用传递。
对于修改调用函数中数据的函数:
- 如果数据对象是内置数据类型,则使用指针
- 如果看到诸如 fixit(&x),则该函数将修改 x。
- 如果数据对象是数组,则只能使用指针。
- 如果数据对象是结构,则使用引用或指针
- 如果数据对象是类对象,则使用引用
默认参数
1 2 3 4 5 6
| int add(int a, int b = 1) { return a + b; }
cout << add(1) << " " << add(1, 3) << endl;
|
函数重载
函数多态是C++在C语言的基础上新增的功能。
- 默认参数使得能够使用不同数目的参数调用同一个函数,
- 函数多态(函数重载)让您能够使用多个同名的函数
如果两个函数的参数数目和类型相同,同时参数的排列顺序也相同,则它们的特征标相同,而变量名是无关紧要的。 C++允许定义名称相同的函数,条件是它们的特征标不同。如果参数数目(和/或)参数类型不同,则特征标也不同。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| void add(double a, double b) { cout << "double: " << (a + b) << endl; }
void add(long a, long b) { cout << "long: " << (a + b) << endl; }
void add(int a, int b) { cout << "int: " << (a + b) << endl; }
void add(int a, double b) { cout << "int double: " << (a + b) << endl; }
void add(int a, long b, double c) { cout << "int long double: " << (a + b + c) << endl; }
add(1.0, 2.0); add(1, 2); add(1L, 2L); add(1, 2.0); add(1, 2L, 3.0);
|
运行结果
1 2 3 4 5
| double: 3 int: 3 long: 3 int double: 3 int long double: 6
|
函数模板
需要多个对不同类型使用同一种算法的函数时,可使用模板
1 2
| template <typename AnyType> template <class AnyType>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| template <typename T> void Swap(T &a, T &b) { T temp; temp = a; a = b; b = temp; }
int i = 10; int j = 20; Swap(i, j); cout << i << " " << j << endl;
double x = 24.5; double y = 81.7; Swap(x, y); cout << x << " " << y << endl;
|
输出结果
参考链接
- 《C++ Primer Plus》