函数探幽
执行到函数调用指令时,程序将在函数调用后立即存储该指令的地址,并将函数参数复制到堆栈(为此保留的内存块),跳回到地址被保存的指令处(这与阅读文章时停下来看脚注,并在阅读完脚注后返回到以前阅读的地方类似)。来回跳跃并记录跳跃位置意味着以前使用函数时需要一定开销。
内联函数
内联函数就是说编译器将使用相应的函数代码替换函数调用。(用空间换时间)要使用:
-
在函数声明前加上关键字inline;
-
在函数定义前加上关键字inline;
通常的做法是省略原型,将整个定义(即函数头和所有函数代码)放在本应该提供函数函数原型的地方。
示例:
// inline.cpp -- using an inline function
#include<iostream>
// an inline function definition
inline double square(double x) { return x*x; };
int main()
{
using namespace std;
double a, b;
double c = 13.0;
a = square(5.0);
b = square(4.5 + 7.5);
cout << "a = " << a << " b = " << b << "\n";
cout << " c = " << c ;
cout << ", c Squared = " << square(c++) << "\n";
cout << "Now C = " << c << endl;
return 0;
}
引用变量
引用是已定义的变量的别名(另一个名称),引用变量的主要途径是作函数的形参。
C和C++使用&符号来指示变量的地址,C++赋予了&符号另一个含义,将其用来声明引用。
int rats;
int & rodents = rats;
示例:
// fistref.cpp -- defining and using a reference
#include<iostream>
int main()
{
using namespace std;
int rats = 10;
int & rodents = rats; // rodents is a reference
cout << "rats = " << rats;
cout << ", rodents = " << rodents << endl;
rodents++;
cout << "rats = " << rats;
cout << ", rodents = " << rodents << endl;
// some implemtations require type casting the follwing
// address to type unsigned
cout << "rats address = " << &rats;
cout << ", rodents address = " << &rodents << endl;
return 0;
}
临时变量、引用参数和const
以下两种情况生成临时变量
- 实参的类型正常,但不是左值
- 实参的类型不正却,但可以转换成正确的类型
**左值是什么?**左值是可以别引用的数据对象,例如,变量、数组元素、结构成员、引用和解引用的指针都是左值。非左值包括字面常量(用引用括号括起来的字符串除外,他们由其地址表示)和包含多项的表达式。在C语言中,左值最初值的是可以出现在赋值语句左边的实体,但这是引用关键字const之前的情况。现在,常规变量和const变量都可以视为左值,因为可以通过地址访问他们。但常规变量属于可以修改的左值,而const变量属于不可修改的左值。
尽可能使用const
- 使用const可以避免无意间修改数据的编程错误。
- 使用const使函数能够处理const和非const实参,否则只能接受非const数据。
- 使用const引用使函数能够正确生成并使用临时变量。
引用使用指导
对于使用传递值而不做修改的函数
- 如果数据对象很小,如内置数据类型或小型结构,则按值传递。
- 如果数据对象是数组,这使用指针,因为这是唯一选择,并将指针声明为指向const的指针。
- 如果数据对象是较大的结构,则使用const指针或const引用,以提高程序的效率。这样可以节省复制结构所需的时间和空间。
- 如果数据对象是类对象,则使用const引用。类设计的语义常常要求使用引用,这是C++新增这项特性的主要原因。因此,传递类对象参数的标准方式是按值传递。
对于修改调用函数中数据的函数
- 如果数据对象是内置数据类型,则使用指针。如果看到诸如fixit(&x)这样的代码(其中x是int)则很明显,该函数将修改x。
- 如果数据类型是数组,则只能使用指针。
- 如果数据类型是结构,则使用引用或指针。
- 如果数据对象是类对象,则使用引用。
默认参数
给函数设置默认参数时,默认参数设置在函数声明中,函数定义不需要。