8.1 内联函数
使用内联函数
#include
using namespace std;
inline double square(double x) { return x * x; }
int main(){
double a;
a = square(5.0);
cout << "a = " << a << endl;
return 0;
}
8.2 引用变量
将引用用作函数参数(使用const)
#include
using namespace std;
double cube(const double &ra);
int main(){
double x = 3.0;
cout << cube(x) << " = cube of " << x << endl;
cout << cube(5) << " = cube of " << "5" << endl;
cout << cube(x+5) << " = cube of " << x+5 << endl;
return 0;
}
double cube(const double &ra) {
return ra*ra*ra;
}
将引用用于结构
#include
#include
using namespace std;
struct free_throws {
string name;
int made;
int attempts;
float percent;
};
void set_pc(free_throws &ft);
void display(const free_throws &ft);
free_throws &accumulate(free_throws &target, const free_throws &source);
int main(){
free_throws one = { "Rick", 13, 14 }; // 最后一个值没赋值,为空
free_throws two = { "Jack", 10, 16 };
free_throws team = { "All", 0, 0 };
set_pc(one); // 赋值
display(one); // 展示
display(accumulate(team, one)); // 汇总
return 0;
}
void set_pc(free_throws &ft) { // 要修改原始数据,不加const
if (ft.attempts != 0)
ft.percent = 100.0 * float(ft.made) / float(ft.attempts);
else
ft.attempts = 0;
}
void display(const free_throws &ft) {
cout << "Name: " << ft.name << endl;
cout << "Made: " << ft.made << '\t';
cout << "Attempts: " << ft.attempts << '\t';
cout << "Percent: " << ft.percent << endl;
}
// 把函数的返回值定义为结构体引用
free_throws &accumulate(free_throws &target, const free_throws &source) {
target.attempts += source.attempts;
target.made += source.made;
set_pc(target);
return target;
}
将引用用于类的对象
#include
#include
using namespace std;
string version1(const string &s1, const string &s2);
const string &version2(string &s1, const string &s2);
// const string &version3(string &s1, const string &s2);
int main(){
string input;
string copy;
string result;
cout << "Enter a string: ";
getline(cin, input);
copy = input;
cout << "You string: " << input << endl;
result = version1(input, "***"); // 在字符串前后都加上***
cout << "Your string enhanced: " << result << endl;
cout << "Your input: " << input << endl;
cout << "-------------------------------------" << endl;
result = version2(input, "###");
cout << "Your string enhanced: " << result << endl;
cout << "Your input: " << input << endl;
//cout << "-------------------------------------" << endl;
//input = copy;
//result = version3(input, "@@@");
//cout << "Your string enhanced: " << result << endl;
//cout << "Your input: " << input << endl;
return 0;
}
// const string &s2 对应的是 "***"
// 当使用const限定符时,会产生临时变量并进行类型转换
string version1(const string &s1, const string &s2) {
string temp;
temp = s2 + s1 + s2;
return temp;
}
// 返回一个string类的对象的引用
const string &version2(string &s1, const string &s2) {
s1 = s2 + s1 + s2;
return s1;
}
/*错误的使用方法:返回临时变量的引用
const string &version3(string &s1, const string &s2) {
string temp;
temp = s2 + s1 + s2;
return temp;
}
*/
对象、继承和引用
#include
#include
#include
#include
using namespace std;
const int LIMIT = 5;
void file_it(ostream &os, double fo, const double fe[], int n);
int main(){
fstream fout;
// 先在路径中里新建这个txt文件
const char *fn = "ep-data.txt";
fout.open(fn);
if (!fout.is_open()) {
cout << "Can't open " << fn << "." << endl;
exit(EXIT_FAILURE);
}
double objective; // 物镜的焦距
cout << "Enter the focal length of telescope objective in mm: ";
cin >> objective;
double eps[LIMIT]; // 目镜的焦距
for (int i = 0; i < LIMIT; i++) {
cout << "Eyepieces #" << i + 1 << ": ";
cin >> eps[i];
}
file_it(cout, objective, eps, LIMIT); // 在终端上显示
file_it(fout, objective, eps, LIMIT); // 在文件中显示
cout << "Done." << endl;
return 0;
}
// ostream &os 基类的引用,可以指向基类的对象,也可以指向派生类的对象
void file_it(ostream &os, double fo, const double fe[], int n) {
os << "Focal length of objective: " << fo << endl;
os << "f.l. eyepieces" << " magnification" << endl;
for (int i = 0; i < n; i++) {
os << " " << fe[i] << " " << int(fo / fe[i] + 0.5) << endl;
}
}
8.3 默认参数
默认参数的用法(取出字符串的前n个值)
#include
using namespace std;
const int ArSize = 80;
char *left(const char *str, int n = 1); // 默认参数n=1
int main(){
char sample[ArSize];
cout << "Enter a string: " << endl;
cin.get(sample, ArSize);
char *ps = left(sample, 4);
cout << ps << endl;
delete[] ps; // 注意new和delete成对出现
ps = left(sample); // 使用默认参数
cout << ps << endl;
delete[] ps;
return 0;
}
char *left(const char *str, int n) {
int m = 0;
while (m < n && str[m] != '\0') m++; // 确定字符串长度
char *p = new char[m + 1];
int i;
for (i = 0; i < m; i++) {
p[i] = str[i];
}
p[i] = '\0'; // 最后要补上一个空字符
return p;
}
8.4 函数重载
函数重载示例(取出字符串/数字的前n个值)
#include
using namespace std;
const int ArSize = 80;
char *left(const char *str, int n = 1);
unsigned long left(unsigned long num, unsigned int ct);
int main(){
const char *trip = "Hawaii";
unsigned long n = 12345678;
int i;
char *temp;
for (i = 0; i < 10; i++) {
cout << left(n, i) << endl;
temp = left(trip, i);
cout << temp << endl;
delete[] temp;
}
return 0;
}
char *left(const char *str, int n) {
int m = 0;
while (m < n && str[m] != '\0') m++; // 确定字符串长度
char *p = new char[m + 1];
int i;
for (i = 0; i < m; i++) {
p[i] = str[i];
}
p[i] = '\0'; // 最后要补上一个空字符
return p;
}
unsigned long left(unsigned long num, unsigned int ct) {
unsigned long n = num;
unsigned int digits = 1;
if (num == 0 || ct == 0) return 0; // 特殊情况
while (n /= 10) digits++; // 判断数字有几位
if (digits > ct) {
ct = digits - ct; // 要除几次10
while (ct--) num /= 10;
return num;
}
else
return num;
}
8.5 函数模板
函数模板示例(交换两个数的值)
#include
using namespace std;
template
void Swap(T &a, T &b);
int main(){
int i = 10;
int j = 20;
cout << "i, j = " << i << ", " << j << "." << endl;
Swap(i, j);
cout << "Afer swap, i, j = " << i << ", " << j << "." << endl;
double x = 24.5;
double y = 81.7;
cout << "x, y = " << x << ", " << y << "." << endl;
Swap(x, y);
cout << "Afer swap, x, y = " << x << ", " << y << "." << endl;
return 0;
}
template
void Swap(T &a, T &b) {
T temp;
temp = a;
a = b;
b = temp;
}
重载的模板示例(交换两个数或两个数组)
#include
using namespace std;
template
void Swap(T &a, T &b);
template
void Swap(T a[], T b[], int n);
const int LIMIT = 8;
void show(int arr[], int n);
int main(){
int i = 10;
int j = 20;
cout << "i, j = " << i << ", " << j << "." << endl;
Swap(i, j);
cout << "Afer swap, i, j = " << i << ", " << j << "." << endl;
int d1[LIMIT] = { 0,7,0,4,1,7,7,6 };
int d2[LIMIT] = { 0,7,2,0,1,9,6,9 };
cout << "Original arrays: " << endl;
show(d1, LIMIT);
show(d2, LIMIT);
Swap(d1, d2, LIMIT);
cout << "After swap: " << endl;
show(d1, LIMIT);
show(d2, LIMIT);
return 0;
}
template
void Swap(T &a, T &b) {
T temp;
temp = a;
a = b;
b = temp;
}
template
void Swap(T a[], T b[], int n) {
T temp;
for (int i = 0; i < n; i++) {
temp = a[i];
a[i] = b[i];
b[i] = temp;
}
}
void show(int arr[], int n) {
for (int i = 0; i < n; i++) {
cout << arr[i] << " ";
}
cout << endl;
}
调用函数时的最佳匹配(打印数组内容)
#include
using namespace std;
template
void ShowArray(T arr[], int n);
template
void ShowArray(T *arr[], int n);
struct debts {
char name[50]; // 名字
double amount; // 数量
};
int main(){
int things[6] = { 13,31,103,301,310,130 };
struct debts mr_E[3] =
{
{"Rick", 2400.00},
{"Jack", 1300.0},
{"Rose", 1800.0}
};
double *pd[3]; // 3个元素的数组,每个元素都是指针
for (int i = 0; i < 3; i++) {
pd[i] = &mr_E[i].amount;
}
ShowArray(things, 6);
// 更匹配 void ShowArray(T *arr[], int n)
// 会打印出来指针指向的数值
ShowArray(pd, 3);
return 0;
}
template
void ShowArray(T arr[], int n) {
cout << "template A:" << endl;
for (int i = 0; i < n; i++)
cout << arr[i] << " ";
cout << endl;
}
template
void ShowArray(T *arr[], int n) {
cout << "template B:" << endl;
for (int i = 0; i < n; i++)
cout << *arr[i] << " ";
cout << endl;
}
引导编译器使用指定函数(打印较小的值)
#include
using namespace std;
template
T lesser(T a, T b) { // 函数1 返回较小值
return a < b ? a : b;
}
int lesser(int a, int b) { // 函数2 返回绝对值的较小值
a = a < 0 ? -a : a;
b = b < 0 ? -b : b;
return a < b ? a : b;
}
int main(){
int m = 20, n = -30;
double x = 15.5, y = -25.9;
// 非模板函数优先,调用的是函数2
cout << lesser(m, n) << endl;
// 非模板函数不是最优(要进行类型转换),调用的是函数1
cout << lesser(x, y) << endl;
// 尖括号<>告诉编译器使用模板函数,调用函数1
cout << lesser<>(m, n) << endl;
// 把x和y强制转换为int类型,再使用模板函数2
cout << lesser(x, y) << endl;
return 0;
}